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

时间:2015-02-06 22:09:06

标签: python django foreign-keys django-generic-views

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

型号:

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有关。但是,在发布之前,我尝试了许多不同的东西,我想到尝试获取像管理页面一样工作的字段。我只是遗漏了我在这里尝试过的烂摊子。我也在文档中找不到任何关于我出错的地方。

我没有包含我的模板/网址代码,因为我认为这不是问题所在。我可以再次添加事件,而不是EventDay部分。但是我对这一切都很陌生,所以如果你需要我发布更多代码我会的。

1 个答案:

答案 0 :(得分:6)

您正在寻找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)

要更多地了解类基本视图结构以及要覆盖的方法等,checkout Classy Class Based Views