Menu
CoddyTech

出席回复表单

本课属于 Coddy Django 学习旅程的“表单”单元。第 16 课,共 20 课。

访客想要表示他们会来。项目新增了一个 RSVP 模型,它通过 ForeignKey 关联到 Event(related_name="rsvps"),每个活动页面的“会来吗?”标题下都有一个表单。

RSVP 表单会询问姓名和邮箱,不会询问活动:访客正在查看该活动的页面,如果添加一个字段,就会让他们选择其他活动。不要将活动放进 fields,而是在视图中设置它。

form.save(commit=False) 会创建对象但不保存,这样你就能先设置其他内容。商店的订单表单不会询问状态:

form = OrderForm(request.POST)
if form.is_valid():
    order = form.save(commit=False)
    order.status = "new"
    order.save()

直接调用 form.save() 会立即保存这一行数据,而必填的 ForeignKey 留空会导致 IntegrityError 错误。

challenge icon

挑战

中等

让访客报名参加活动。

  1. 在 events/forms.py 中,为 RSVP 编写一个 ModelForm RSVPForm,只包含 name 和 email。
  2. 在 event_detail 中,将 RSVPForm 作为 form 传给页面。收到 POST 请求时,用 request.POST 创建表单。
  3. 如果表单有效,就使用 commit=False 保存,设置活动并保存,然后添加 You're on the list! 并重定向到活动页面。如果表单无效,就再次显示表单。

报名参加周五爵士之夜:你会看到 You're on the list!

亲手试试

from django.contrib import messages
from django.shortcuts import get_object_or_404, redirect, render

from .forms import EventForm
from .models import Event


def event_list(request):
    q = request.GET.get("q", "")
    events = Event.objects.all()
    if q:
        events = events.filter(title__icontains=q)
    return render(request, "events/event_list.html", {"events": events, "q": q})


def event_detail(request, pk):
    event = get_object_or_404(Event, pk=pk)
    return render(request, "events/event_detail.html", {"event": event})


def new_event(request):
    if request.method == "POST":
        form = EventForm(request.POST)
        if form.is_valid():
            event = form.save()
            messages.success(request, "Your event was added.")
            return redirect("events:detail", pk=event.pk)
    else:
        form = EventForm()
    return render(request, "events/new_event.html", {"form": form})


def edit_event(request, pk):
    event = get_object_or_404(Event, pk=pk)
    if request.method == "POST":
        form = EventForm(request.POST, instance=event)
        if form.is_valid():
            form.save()
            messages.success(request, "Your changes were saved.")
            return redirect("events:detail", pk=event.pk)
    else:
        form = EventForm(instance=event)
    return render(request, "events/edit_event.html", {"form": form, "event": event})


def delete_event(request, pk):
    event = get_object_or_404(Event, pk=pk)
    if request.method == "POST":
        event.delete()
        messages.success(request, "The event was deleted.")
        return redirect("events:list")
    return render(request, "events/delete_event.html", {"event": event})

表单中的所有课

自己练习: Django 在线编辑器