我正在创建一个应用程序,允许人们设置可能跨越多天的教学活动。这是我的一些代码:
型号:
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部分。但是我对这一切都很陌生,所以如果你需要我发布更多代码我会的。
答案 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。