0

整天都在努力完成这项工作。我有一个主要模型是入门。一个条目可以包括多个班次。这是存储工作时间的应用程序的一部分。这是创建条目的视图:

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/ NOT NULL 约束处​​的 IntegrityError 失败:shift_shift.entry_id”。我试图弄清楚班次出了什么问题,所以我将保存班次的块注释掉(从“if len(errors)”到“return HttpResponseRedirect.”),以便它返回到带有表单的视图. 然后我将 {{ shifts }} 放入我的模板中,看看里面有什么。当我这样做时,它以:“NoReverseMatch at /time_manager/entry/create/ Reverse for 'edit' with arguments '()' and keyword arguments '{'pk': None}' not found. 1 pattern(s)试过: ['time_manager/entry/shift/edit/(?P(\d+))/$']" 就好像我试图使用 {% url %} 标记引用的视图没有' 不存在。所以我猜测当我尝试保存表单集的表单时会出现问题。但是,我一遍又一遍地阅读 django 文档,这是存储表单集表单的方式,不是吗?

4

1 回答 1

1

好的,我以全新的头脑查看了我的代码,然后我想到了。我想确保首先正确构建条目和每个班次,然后仅在它们不违反任何规则时才保存它们。正如您在上面看到的:我将两者都保存为 commit=False。然而,这意味着该条目尚未分配主键。主键是我的班次模型上的 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。

于 2016-06-30T12:40:32.797 回答