Skip to main content
 首页 » 编程设计

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

2025年05月04日39kevingrace

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

模型:

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

在管理员中,当我添加一个事件时,它工作得很好,允许我根据需要向事件添加任意天数。但是管理外部的事件添加页面只显示来自 Event 的字段,而不是 EventDay。

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

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

请您参考如下方法:

您正在寻找 inline formset .

CreateView 可以与此一起使用,但我认为您应该改用 TemplateView(CreateView 的基类),它更易于扩展/修改。

# 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) 

要了解更多关于类基 View 结构和覆盖哪个方法等信息,checkout Classy Class Based Views .