Django 2.1.3レイヤーを見てCBVでフォーム処理を行います.

21056 ワード

目次
  • 1.基本フォーム
  • .ModelForm
  • .モデルとrequest.user
  • .AJAX例
  • ←CBVビューを内蔵しています.カタログ全体にmixinsを使用しています.
    フォーム処理は通常3つの場合があります.
  • 初期GET(空白またはプレ充填)
  • 無効データを用いてPOST(通常はエラーの後にフォームを再表示する)
  • を行う.
  • 有効データPOST(データを処理し、通常リダイレクトする)を使用して、これを実現すると、通常、多くのリピートされるサンプルコードが発生します.このような状況を回避するために、Djangoはフォーム処理のためにクラスベースの汎用ビューのセットを提供する.
  • 1.基本フォーム
    簡単なフォームを与えます.
    #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().form_valid(form)
    
    注意:1.FormViewはTemplateResonseMixinから継承されていますので、ここでtemplate_を使うことができます.name2.form_valid()のデフォルト実装は簡単にsuccess_にリダイレクトすることです.url
    このように使っています.
    <form action="{% url 'polls:cbv_form_view' %}" method="POST" enctype="multipart/form-data">
            {% csrf_token %}
            {{ form.name.label }}{{ form.name }}<br>
            {{ form.message.label }}{{ form.message }}<br>
            <input type="submit" value="  ">
        form>
    
    2.ModelForm
    一般的なビューとmodelが一緒に働くのは無意味です.これらの一般的なビューは自動的にModelFormを作成します.それらが使用するモデルクラスを決定できる限り、次の3つの方法で使用できます.
  • は、model属性が与えられると、モデルクラスを使用する.
  • get_オブジェクトを返すと、そのオブジェクトのクラスが使用されます.
  • にquerysetが与えられた場合、クエリセットのモデルが使用される.
  • ModelFormビューでform_valid()の実装は自動保存モデルです.特別な要求があれば、それをカバーできます.次の例を参照してください.
    あなたはCreateViewやUpdateViewのためにsuccessを提供する必要さえありません.url-get_ならabsoute_url()は、モデルオブジェクト上でこの方法を使用することができます.
    カスタムModelFormを使用する場合(例えば追加の検証を追加する)は、ビュー上でform_を設定するだけです.クラスでいいです
    注意カスタムフォームクラスを指定する場合は、まだモデルを指定してください.クラスはModelFormかもしれません.
    まず、私たちはget_absolute_url()をAuthorクラスに追加したいです.
    #models.py
    from django.db import models
    from django.urls import reverse
    
    class Author(models.Model):
        name = models.CharField(max_length=200)
    
        def get_absolute_url(self):
        	#   :  author-detail       -> yourapp:author-detail           
            return reverse('author-detail', kwargs={'pk': self.pk})
    
    ここでCBVの一般的なビューを設定するにはどうすればいいですか?
    #views.py 
    
    from django.urls import reverse_lazy
    from django.views.generic.edit import CreateView, DeleteView, UpdateView
    from myapp.models import Author
    
    class AuthorCreate(CreateView):
        model = Author
        fields = ['name']
    
    class AuthorUpdate(UpdateView):
        model = Author
        fields = ['name']
    
    class AuthorDelete(DeleteView):
        model = Author
        #   :  author-list       -> yourapp:author-list           
        success_url = reverse_lazy('author-list')
    
    注意私達はここでreverse_を使わなければなりません.lazy()は、reverse()ではなく、ファイル導入時にURLが読み込まれていないためです.
    fields属性の働き方は、ModelForm内部のMeta類のfieldsと同じです.フォームクラスを別の方法で定義しない限り、この属性は必要です.そうでない場合、ビューは異常なImproperlyConfigredを誘発します.
    fieldsとformuclass属性を同時に指定すると、異常ImproperlyConfigredが発生します.
    最後に、これらの新しいビューをURLconfに関連付ける.
    # urls.py 
    from django.urls import path
    from myapp.views import AuthorCreate, AuthorDelete, AuthorUpdate
    
    urlpatterns = [
        # ...
        path('author/add/', AuthorCreate.as_view(), name='author-add'),
        path('author//', AuthorUpdate.as_view(), name='author-update'),
        path('author//delete/', AuthorDelete.as_view(), name='author-delete'),
    ]
    
    注意
    これらのビューは、SingleObject TemplateResonsemixinから引き継がれています.これはtemplatemutaunameを使用してtemplatembeベースのモデルを構築します.
    この例では、
  • CreateViewとUpdateViewはmyapp/author_form.htmlを使用しています(テンプレート名を変えることができます.ビュークラスにtemplatemuneまたはtemplatemutを設定できます.)
  • DeleteViewはmyapp/author_confirm_delete.htmlを使用しています.
    3.モデルと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, on_delete=models.CASCADE)
    
        # ...
    
    ビューでは、あなたがFieldsのリストにcreatedubyフィールドを含んでいないことを確認し、 _confirm_delete.htmlを上書きしてユーザを追加します.
    # 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().form_valid(form)
    
    このビューを装飾するためには、装飾器のlogiingurquired()を使用するか、またはformuvalid()で未許可のユーザを処理する必要があります.
    4.AJAX例
    これは簡単な例であり、AJAX要求及び「通常」POST要求に適用されるフォームの実装方法を示している.
    from django.http import JsonResponse
    from django.views.generic.edit import CreateView
    from myapp.models import Author
    
    class AjaxableResponseMixin:
        """
        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().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().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']