django 1.8公式ドキュメント翻訳:3-4-3クラスベースのビューを使用してフォームを処理

6890 ワード

クラスベースのビュー処理フォームの使用
フォームの処理には通常3つのステップがあります.
  • 初期のGET(空白またはプリフィルフォーム)
  • 不正なデータを有するPOST(通常はフォームとエラー情報を再表示)
  • .
  • 正当なデータを有するPOST(データを処理してリダイレクト)
  • これらの機能を自分で実装すると、多くのサンプルコードが重複することがよくあります(ビューでフォームを使用するを参照).これを回避するために、Djangoはクラスベースの一連のビューをフォームの処理に使用します.
    基本フォーム
    簡単な連絡先フォームに基づきます.
    #forms.py
    
    from django import forms
    
    class ContactForm(forms.Form):
        name = forms.CharField()
        message = forms.CharField(widget=forms.Textarea)
    
        def send_email(self):
            # send email using the self.cleaned_data dictionary
            pass
    FormViewを使用してビューを構築できます.
    #views.py
    
    from myapp.forms import ContactForm
    from django.views.generic.edit import FormView
    
    class ContactView(FormView):
        template_name = 'contact.html'
        form_class = ContactForm
        success_url = '/thanks/'
    
        def form_valid(self, form):
            # This method is called when valid form data has been POSTed.
            # It should return an HttpResponse.
            form.send_email()
            return super(ContactView, self).form_valid(form)

    注意:
  • FormViewTemplateResponseMixinを継承するので、ここではtemplate_nameを使用することができる.
  • form_valid()のデフォルトのインプリメンテーションは、単純にsuccess_urlにリダイレクトされるだけである.

  • モデルのフォーム
    汎用ビューは、モデルが一緒に動作するときに本当に光を放つことです.これらの一般的なビューでは、どのモデルクラスを使用するかがわかる限り、ModelFormが自動的に作成されます.
  • model属性が与えられた場合、モデルクラスが使用される.
  • get_object()がオブジェクトを返す場合、そのオブジェクトのクラスが使用されます.
  • querysetが与えられた場合、クエリセットのモデルが使用される.

  • モデルフォームは、モデルを自動的に保存するform_valid()の実装を提供します.特別なニーズがあれば、それをカバーすることができます.次の例を参照してください.CreateViewおよびUpdateViewsuccess_urlを提供する必要はありません.モデルオブジェクトが存在する場合、get_absolute_url()が使用されます.
    カスタムModelForm(追加の検証など)を使用する場合は、form_classを簡単にビューに設定するだけです.

    カスタムフォームクラスを指定する場合は、form_classModelFormであってもモデルを指定する必要があります.
    まず、get_absolute_url()Authorクラスに追加する必要があります.
    #models.py
    
    from django.core.urlresolvers import reverse
    from django.db import models
    
    class Author(models.Model):
        name = models.CharField(max_length=200)
    
        def get_absolute_url(self):
            return reverse('author-detail', kwargs={'pk': self.pk})

    その後、CreateViewマシンパートナーを使用して実際の作業を行うことができます.ここでは、共通のクラスベースのビューをどのように構成するかに注意してください.私たち自身は論理を書いていません.
    #views.py
    
    from django.views.generic.edit import CreateView, UpdateView, DeleteView
    from django.core.urlresolvers import reverse_lazy
    from myapp.models import Author
    
    class AuthorCreate(CreateView):
        model = Author
        fields = ['name']
    
    class AuthorUpdate(UpdateView):
        model = Author
        fields = ['name']
    
    class AuthorDelete(DeleteView):
        model = Author
        success_url = reverse_lazy('author-list')


    ここでは、このファイルのインポート時にURLがまだロードされていないため、reverse_lazy()ではなくreverseを使用する必要があります.fields属性の動作は、ModelFormの内部Metaクラスのfields属性と同じである.フォームクラスを別の方法で定義しない限り、ImproperlyConfiguredの例外が発生しない場合は、この属性が必要です.fieldsform_classのプロパティを同時に指定すると、ImproperlyConfiguredの例外が発生します.
    Changed in Django 1.8:
    
      fields          ,               。
    Changed in Django 1.8:
    
      ,  fields  form_class      ,       fields。

    最後に、これらの新しいビューをURLconfに配置します.
    #urls.py
    
    from django.conf.urls import url
    from myapp.views import AuthorCreate, AuthorUpdate, AuthorDelete
    
    urlpatterns = [
        # ...
        url(r'author/add/$', AuthorCreate.as_view(), name='author_add'),
        url(r'author/(?P[0-9]+)/$', AuthorUpdate.as_view(), name='author_update'),
        url(r'author/(?P[0-9]+)/delete/$', AuthorDelete.as_view(), name='author_delete'),
    ]


    これらのフォームは、SingleObjectTemplateResponseMixinを継承し、template_name_suffix を使用し、モデルに基づいてtemplate_nameを構築する.
    この例では、
  • CreateViewおよびUpdateViewは、myapp/author_form.html
  • を用いる.
  • DeleteView myapp/author_confirm_delete.html
  • を使用する.CreateViewUpdateViewのテンプレートを分離したい場合は、ビュークラスのtemplate_nameまたはtemplate_name_suffixを設定できます.
    モデルとrequest.user
    CreateViewを使用してオブジェクトを作成したユーザーを追跡するには、カスタムModelFormを使用してこれを実現します.まず、モデルに外部キー関連付けを追加します.
    #models.py
    
    from django.contrib.auth.models import User
    from django.db import models
    
    class Author(models.Model):
        name = models.CharField(max_length=200)
        created_by = models.ForeignKey(User)
    
        # ...

    このビューでは、編集するフィールドのリストにcreated_byが含まれていないことを確認し、form_valid()を上書きしてユーザーを追加します.
    #views.py
    
    from django.views.generic.edit import CreateView
    from myapp.models import Author
    
    class AuthorCreate(CreateView):
        model = Author
        fields = ['name']
    
        def form_valid(self, form):
            form.instance.created_by = self.request.user
            return super(AuthorCreate, self).form_valid(form)
    login_required()を使用してこのビューを装飾するか、form_valid()で認証されていないユーザーを処理する必要があります.
    AJAX例
    次の簡単な例では、AJAXリクエストと「通常」フォームPOSTを同時に動作させるフォームを実装する方法を示します.
    from django.http import JsonResponse
    from django.views.generic.edit import CreateView
    from myapp.models import Author
    
    class AjaxableResponseMixin(object):
        """
        Mixin to add AJAX support to a form.
        Must be used with an object-based FormView (e.g. CreateView)
        """
        def form_invalid(self, form):
            response = super(AjaxableResponseMixin, self).form_invalid(form)
            if self.request.is_ajax():
                return JsonResponse(form.errors, status=400)
            else:
                return response
    
        def form_valid(self, form):
            # We make sure to call the parent's form_valid() method because
            # it might do some processing (in the case of CreateView, it will
            # call form.save() for example).
            response = super(AjaxableResponseMixin, self).form_valid(form)
            if self.request.is_ajax():
                data = {
                    'pk': self.object.pk,
                }
                return JsonResponse(data)
            else:
                return response
    
    class AuthorCreate(AjaxableResponseMixin, CreateView):
        model = Author
        fields = ['name']

    翻訳者:Djangoドキュメントコラボレーション翻訳チーム、原文:Built-in editing views.
    本文はCC BY-NC-SA 3.0プロトコルで発表し、転載は作者の署名と文章の出所を保留してください.
    Djangoドキュメントコラボレーション翻訳チームは人手が不足しており、興味のある友达は私たちに参加することができ、完全に公益的です.交流群:467338606.