クラスベースのビューを使用したフォーム処理—Djangoドキュメント
クラスベースのビューによるフォーム処理
フォーム処理には通常、次の3つのパスがあります。
- 初期GET(空白または事前入力されたフォーム)
- 無効なデータを使用したPOST(通常はエラーのあるフォームを再表示します)
- 有効なデータを使用したPOST(データを処理し、通常はリダイレクトします)
これを自分で実装すると、多くの場合、ボイラープレートコードが繰り返されます(ビューでのフォームの使用を参照)。 これを回避するために、Djangoはフォーム処理用の汎用クラスベースビューのコレクションを提供します。
基本的なフォーム
お問い合わせフォームを指定します。
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
を使用して作成できます。
from myapp.forms import ContactForm
from django.views.generic.edit import FormView
class ContactFormView(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)
ノート:
- FormViewは TemplateResponseMixin を継承するため、ここでは template_name を使用できます。
- form_valid()のデフォルトの実装は、単に success_url にリダイレクトします。
モデルフォーム
モデルを操作するとき、一般的なビューは本当に輝いています。 これらの汎用ビューは、使用するモデルクラスを決定できる限り、 ModelForm を自動的に作成します。
- model 属性が指定されている場合、そのモデルクラスが使用されます。
- get_object()がオブジェクトを返す場合、そのオブジェクトのクラスが使用されます。
- queryset が指定されている場合、そのクエリセットのモデルが使用されます。
モデルフォームビューは、モデルを自動的に保存する form_valid()実装を提供します。 特別な要件がある場合は、これをオーバーライドできます。 例については、以下を参照してください。
CreateView または UpdateView にsuccess_url
を提供する必要はありません。可能な場合は、モデルオブジェクトで get_absolute_url()を使用します。 。
カスタム ModelForm を使用する場合(たとえば、検証を追加する場合)、ビューで form_class を設定します。
まず、 get_absolute_url()をAuthor
クラスに追加する必要があります。
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):
return reverse('author-detail', kwargs={'pk': self.pk})
次に、 CreateView とその仲間を使用して実際の作業を行うことができます。 ここで、一般的なクラスベースのビューを構成していることに注目してください。 自分でロジックを書く必要はありません。
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from myapp.models import Author
class AuthorCreateView(CreateView):
model = Author
fields = ['name']
class AuthorUpdateView(UpdateView):
model = Author
fields = ['name']
class AuthorDeleteView(DeleteView):
model = Author
success_url = reverse_lazy('author-list')
fields
属性は、 ModelForm の内部Meta
クラスのfields
属性と同じように機能します。 別の方法でフォームクラスを定義しない限り、属性は必須であり、そうでない場合、ビューは ImpproperlyConfigured 例外を発生させます。
fields 属性と form_class 属性の両方を指定すると、 ImpproperlyConfigured 例外が発生します。
最後に、これらの新しいビューをURLconfにフックします。
from django.urls import path
from myapp.views import AuthorCreateView, AuthorDeleteView, AuthorUpdateView
urlpatterns = [
# ...
path('author/add/', AuthorCreateView.as_view(), name='author-add'),
path('author/<int:pk>/', AuthorUpdateView.as_view(), name='author-update'),
path('author/<int:pk>/delete/', AuthorDeleteView.as_view(), name='author-delete'),
]
ノート
これらのビューは、 template_name_suffix を使用してモデルに基づいて template_name を構築する SingleObjectTemplateResponseMixin を継承します。
この例では:
- CreateView および UpdateView は
myapp/author_form.html
を使用します - DeleteView は
myapp/author_confirm_delete.html
を使用します
CreateView と UpdateView に別々のテンプレートが必要な場合は、ビュークラスに template_name または template_name_suffix のいずれかを設定できます。
モデルとrequest.user
CreateView を使用してオブジェクトを作成したユーザーを追跡するには、カスタム ModelForm を使用してこれを行うことができます。 まず、モデルに外部キー関係を追加します。
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)
# ...
ビューで、編集するフィールドのリストにcreated_by
が含まれていないことを確認し、 form_valid()をオーバーライドしてユーザーを追加します。
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import CreateView
from myapp.models import Author
class AuthorCreateView(LoginRequiredMixin, CreateView):
model = Author
fields = ['name']
def form_valid(self, form):
form.instance.created_by = self.request.user
return super().form_valid(form)
LoginRequiredMixin は、ログインしていないユーザーがフォームにアクセスできないようにします。 これを省略すると、 form_valid()で許可されていないユーザーを処理する必要があります。
コンテントネゴシエーションの例
これは、APIベースのワークフローと「通常の」フォームPOSTで機能するフォームを実装する方法を示す例です。
from django.http import JsonResponse
from django.views.generic.edit import CreateView
from myapp.models import Author
class JsonableResponseMixin:
"""
Mixin to add JSON 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.accepts('text/html'):
return response
else:
return JsonResponse(form.errors, status=400)
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.accepts('text/html'):
return response
else:
data = {
'pk': self.object.pk,
}
return JsonResponse(data)
class AuthorCreateView(JsonableResponseMixin, CreateView):
model = Author
fields = ['name']