Menu
CoddyTech

メールアドレスごとに1件のRSVP

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

この章はあなたのものです。知っていることを活用して、イベント掲示板に3つの機能を追加します。それぞれの課題では、サイトが何をする必要があるかを示します。コードはあなた次第です。

現在、Adaは金曜のジャズナイトに好きなだけRSVPでき、そのたびに1つの席が確保されます。1つのメールアドレスにつき、イベントごとに1つの席だけを確保できるようにしましょう。

必要なものはすべてそろっています。clean_<field>メソッド、フォームが保持しているイベントのself.event、そしてそのRSVPのself.event.rsvpsです。もう1つ役立つ検索方法があります。email__iexactは大文字と小文字を区別せずにテキストを比較します。Ada@Example.comとada@example.comは同じ受信トレイに届くためです。

challenge icon

チャレンジ

中級

同じメールアドレスから同じイベントへの2回目のRSVPを拒否し、メールフィールドの下にThis email is already on the guest list.と表示します。

  • 大文字と小文字は区別されません。ADA@Example.comはada@example.comと同じです。
  • 同じメールアドレスで別のイベントにRSVPすることはできます。

「Run」を押し、1つのメールアドレスでFriday Jazz Nightに2回RSVPしてください。

自分で試してみよう

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"]

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

    def clean(self):
        cleaned_data = super().clean()
        if self.event.rsvps.count() >= self.event.capacity:
            raise forms.ValidationError("Sorry, this event is full.")
        return cleaned_data

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

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