使用 Django,如何将模型的 ForeignKey 添加到 CreateView?

With Django, how can I add my model's ForeignKey to CreateView?

我正在制作一个应用程序,允许人们设置可能跨越多天的教学活动。这是我的一些代码:

型号:

class Event(models.Model):
    event_name = models.CharField('Event Name', max_length=200)
    short_description = models.TextField('Short Description', max_length=140)

class EventDay(models.Model):
    event = models.ForeignKey(Event)
    day_name = models.CharField(max_length=30)
    start_time = models.DateTimeField('Starting Date and Time')
    end_time = models.DateTimeField('Estimate Ending Time')

观看次数

from .models import Event, EventDay

class EventCreate(LoginRequiredMixin, CreateView):
    model = Event
    fields = ['event_name', 'short_description']

在管理员中,当我添加一个事件时,它运行得非常好,允许我根据需要为事件添加任意天数。但是在管理员之外的事件添加页面只显示来自事件的字段,而不是 EventDay。

我知道就与 EventDay 相关的任何内容而言,我的视图代码看起来有点空洞。但是,在 post 进入这里之前,我尝试了尽可能多的不同方法来尝试获取像管理页面一样工作的字段。我只是遗漏了我在这里尝试过的烂摊子。我在文档中也找不到任何关于我哪里出错的信息。

我没有包含我的 template/url 代码,因为我认为这不是问题所在。同样,我可以添加事件,但不能添加其中的 EventDay 部分。但我是新手,所以如果您需要我 post 更多代码,我会的。

您正在寻找 inline formset

CreateView 可以与此一起使用,但我认为您应该使用 TemplateView(CreateView 的基础 class),它比 extend/modify.

更简单
# forms.py
from django import forms
from .models import Event

class EventForm(forms.ModelForm):
    class Meta:
        model = Event


# views.py
from django.http import HttpResponseRedirect
from django.views.generic import TemplateView
from django.forms.models import inlineformset_factory
from .models import EventDay, Event
from .forms import EventForm

class EventCreate(TemplateView):
    template_name = 'event_create.html'

    def get(self, request, *args, **kwargs):
        "GET forms ready!"
        # get form for Event
        event_form = EventForm()
        # here's the 'magic' inlineformset, better read the
        # django documentation about this
        EventDayFormSet = inlineformset_factory(Event, EventDay)
        formset = EventDayFormSet()
        # add to context and return response
        context = {'form': event_form, 'formset': formset}
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
        "Handle form submission on POST request"
        # get form for Event with POST data
        event_form = EventForm(data=request.POST)
        # get formset for EventDay with POST data
        EventDayFormSet = inlineformset_factory(Event, EventDay)
        formset = EventDayFormSet(data=request.POST)
        if event_form.is_valid() and formset.is_valid():
            # valid forms, OK to save
            event = event_form.save()
            # EventDay needs a ForeignKey for Event since the field is
            # not nullable. Save the forms without committing to database...
            eventdays = formset.save(commit=False)
            for eventday in eventdays:
                # ... and add the ForeignKey field
                eventday.event = event
                eventday.save()
            # TODO use reverse('name_of_the_view_to_redirect_to') instead of '/'
            return HttpResponseRedirect('/')
        # Some error occurred with the forms, display errors and forms
        # so the user can fix it
        context = {'form': event_form, 'formset': formset}
        return self.render_to_response(context)

要进一步了解 class 基本视图结构以及要覆盖的方法等,checkout Classy Class Based Views