一直试图让这项工作整整一天。我有一个入门的主要模型。一个条目可以包括几个班次。这是存储工作时间的应用程序的一部分。这是创建条目的视图:
class EntryCreateView(FormView):
template_name = 'entry/create.html'
form_class = AddWorkDay
success_url = reverse_lazy('time_manager:index')
def get(self, request, ordinal=None, *args, **kwargs):
""" Initiates with a blank form or will populate the day field with the day represented by the passed
ordinal. """
if ordinal:
day = datetime.datetime.fromordinal(int(ordinal))
form = AddWorkDay(initial={'day': day})
else:
form = AddWorkDay()
formset = ShiftFormSet()
return render(request, self.template_name, {'form': form, 'formset': formset})
def post(self, request, ordinal=None, *args, **kwargs):
form = AddWorkDay(data=request.POST)
formset = ShiftFormSet(data=request.POST)
errors = []
shifts = []
if form.is_valid() and formset.is_valid():
# Build entry.
entry = form.save(commit=False)
entry.owner = request.user
errors.extend(entry.validate(request.user))
# Build shift.
for form in formset:
shift = form.save(commit=False)
shift.entry = entry
shifts.append(shift)
errors.extend(shift.validate(request.user))
if len(errors) == 0:
entry.save()
for shift in shifts:
shift.save()
return HttpResponseRedirect(reverse('time_manager:index'))
return render(request, self.template_name, {'form': form, 'formset': formset, 'errors': errors, 'shifts': shifts, 'entry': entry})
当我尝试输入带有班次的条目并按保存时,它会终止说: "在/ time_manager / entry / create /的IntegrityError NOT NULL约束失败:shift_shift.entry_id"。我试图弄清楚班次出了什么问题,所以我评论了保存班次的区块(从"如果len(错误)"到"返回HttpResponseRedirect。" )这样它将返回带有表单的视图。然后我将{{shifting}}放入我的模板中,看看那里有什么。当我这样做时,它终止于:" NoReverseMatch at / time_manager / entry / create / 反转'编辑'参数'()'和关键字参数' {' pk':无}'未找到。尝试了1种模式:[' time_manager / entry / shift / edit /(?P(\ d +))/ $']"好像我试图使用{%url%}标签引用一个不存在的视图。因此,当我尝试保存formset的形式时,我猜测出现了问题。但是,我一遍又一遍地阅读django文档,这是存储formset表单的方法,不是吗?
答案 0 :(得分:1)
好的,我头脑清醒,看着我的代码,然后发生在我身上。我想确保首先正确构建条目和每个班次,然后只有在不违反任何规则时才保存它们。正如您在上面所看到的:我用commit = False保存它们。这意味着该条目尚未分配主键。主键是我的shift模型上的ForeignKeyField所需要的。这就是为什么Django没能保存它。
我稍微改变了方法的顺序。这是工作代码:
def post(self, request, ordinal=None, *args, **kwargs):
form = AddWorkDay(data=request.POST)
formset = ShiftFormSet(data=request.POST)
errors = []
shifts = []
if form.is_valid() and formset.is_valid():
# Build entry.
entry = form.save(commit=False)
entry.owner = request.user
errors.extend(entry.validate(request.user))
# Build shift.
for form in formset:
shift = form.save(commit=False)
shifts.append(shift)
errors.extend(shift.validate(request.user))
# If there are no errors, save the entry ans it's shifts.
if len(errors) == 0:
entry.save()
for shift in shifts:
shift.entry = entry
shift.save()
return HttpResponseRedirect(reverse('time_manager:index'))
return render(request, self.template_name, {'form': form, 'formset': formset, 'errors': errors, 'shifts': shifts, 'entry': entry})
注意第二次如何保存条目(没有commit = False),然后分配给shift。