Menu
CoddyTech

Một ModelForm

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

Hãy xem EventForm và model Event cạnh nhau: cùng một bộ trường được viết hai lần. ModelForm tạo các trường từ model. Với model Book:

from .models import Book


class BookForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ["title", "author", "pages"]

Lớp Meta bên trong chỉ định model và các trường cần dùng. Mỗi trường của model trở thành trường tương ứng trong form, còn blank=True khiến trường đó không bắt buộc. Danh sách này là bắt buộc, vì vậy một trường được thêm vào model sau này sẽ không vô tình xuất hiện trong form công khai.

clean_<field>() và clean() hoạt động tương tự khi đặt cạnh Meta. Form cũng tự lưu: form.save() tạo một hàng từ cleaned_data rồi trả về hàng đó.

challenge icon

Thử thách

Dễ

Chuyển EventForm thành ModelForm.

  1. Trong events/forms.py, xóa sáu dòng trường và thêm một Meta chỉ định Event cùng sáu trường: title, date, end_date, place, description, capacity. Giữ lại clean_date() và clean().
  2. Trong new_event, thay Event.objects.create() bằng form.save().

Thêm một sự kiện có ngày trong quá khứ: bạn vẫn thấy The date cannot be in the past.

Tự làm thử

import datetime

from django import forms


class EventForm(forms.Form):
    title = forms.CharField(max_length=100)
    date = forms.DateField()
    end_date = forms.DateField(required=False)
    place = forms.CharField(max_length=100)
    description = forms.CharField(widget=forms.Textarea, required=False)
    capacity = forms.IntegerField(min_value=1)

    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

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

Tự luyện tập: Playground Django