Menu
CoddyTech

Một sự kiện hoàn chỉnh

Thuộc phần Biểu mẫu trong hành trình Django của Coddy. Bài học 17 trên 20.

Lớp làm đồ gốm có 2 chỗ và 2 khách, nhưng biểu mẫu vẫn nhận thêm khách. Quy tắc này thuộc về biểu mẫu, nhưng chỉ view mới biết biểu mẫu dành cho sự kiện nào.

Biểu mẫu là một lớp Python, nên bạn có thể tự viết __init__. Nhận giá trị bổ sung dưới dạng đối số từ khóa, lưu giá trị đó vào self và truyền phần còn lại cho super().__init__(). Biểu mẫu đặt giá cần có món đồ đấu giá:

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

View truyền món đồ mỗi lần tạo biểu mẫu: BidForm(request.POST, item=item). Khai báo item trong chữ ký hàm giúp giữ nó ngoài **kwargs; biểu mẫu của Django không biết tham số này và sẽ phát sinh TypeError.

challenge icon

Thử thách

Trung bình

Sự kiện đã kín chỗ sẽ từ chối đăng ký tham dự.

  1. Trong events/forms.py, thêm cho RSVPForm một __init__ để lưu tham số từ khóa event vào self.event và chuyển các tham số còn lại cho super().__init__.
  2. Trong clean() của lớp này, khi khách lấp đầy capacity, hãy phát sinh lỗi Sorry, this event is full. Nếu còn một chỗ, khách vẫn có thể đăng ký.
  3. Trong event_detail, truyền event vào cả hai lần gọi RSVPForm.

Đăng ký tham dự lớp học làm gốm: bạn sẽ thấy Sorry, this event is full.

Tự làm thử

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 iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Biểu mẫu

Tự luyện tập: Playground Django