Menu
CoddyTech

イベント全体

CoddyのDjangoジャーニー「フォーム」セクションの一部。レッスン 17/20。

陶芸教室には2つの席と2人のゲストがいますが、それでもフォームはそれ以上の人数を受け入れてしまいます。このルールはフォームに記述すべきですが、フォームがどのイベント用なのかを知っているのはビューだけです。

フォームはクラスなので、追加の引数を受け取ることができます。__init__でキーワード引数として受け取り、selfに保持して、残りの引数をDjangoの__init__に渡します。オークション品目を必要とする入札フォームの例です。

class BidForm(forms.Form):
    amount = forms.IntegerField()

    def __init__(self, *args, item=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.item = item

    def clean_amount(self):
        amount = self.cleaned_data["amount"]
        if amount <= self.item.top_bid:
            raise forms.ValidationError("Bid more than the top bid.")
        return amount

ビューはフォームを作成するたびに品目を渡します。BidForm(request.POST, item=item)。シグネチャでitemを指定すると、**kwargsには含まれません。Djangoのフォームはそれを認識せず、TypeErrorを発生させるためです。

challenge icon

チャレンジ

中級

満席のイベントへの出欠申し込みを Sorry, this event is full. で拒否します。

  • RSVPForm にキーワード引数 event としてイベントを渡し、フォーム全体の検証で使用します。
  • 残りの席が1席のイベントには、ゲストをもう1人受け入れます。
  • event_detail がフォームを作成するすべての箇所で、イベントを渡します。

「実行」を押して、Pottery Class に出欠を申し込みます。

自分で試してみよう

import datetime

from django import forms

from .models import RSVP, Event


class EventForm(forms.ModelForm):
    class Meta:
        model = Event
        fields = ["title", "date", "end_date", "place", "description", "capacity"]

    def clean_date(self):
        date = self.cleaned_data["date"]
        if date < datetime.date.today():
            raise forms.ValidationError("The date cannot be in the past.")
        return date

    def clean(self):
        cleaned_data = super().clean()
        date = cleaned_data.get("date")
        end_date = cleaned_data.get("end_date")
        if date and end_date and end_date < date:
            raise forms.ValidationError("The event cannot end before it starts.")
        return cleaned_data


class RSVPForm(forms.ModelForm):
    class Meta:
        model = RSVP
        fields = ["name", "email"]
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

フォームのすべてのレッスン

自分で練習してみよう: Djangoプレイグラウンド