Django保存modelformset_factory

时间:2018-09-06 13:52:30

标签: django formview

保存表单集时,它并没有验证和尊重我已设置为唯一的模型字段,因此,如果我故意复制字段以对其进行测试,则会出现完整性错误。

我的猜测是表单集本身可以正确验证,但是由于唯一字段是我在save(commit = False)过程中必须分配的内容,因此它从未得到验证。这有道理吗?

请问我有什么想念的吗?

我的代码:

class ClientCreate(LoginRequiredMixin, FormView):
    def dispatch(self, *args, **kwargs):
        self.case = Case.objects.get(pk=kwargs['case_pk'])
        self.num_clients = self.case.number_clients
        return super().dispatch(*args, **kwargs)

template_name = 'clients/client_form.html'
form_class = modelformset_factory(Client, ClientForm,
                                  min_num=2, max_num=2, extra=0,
                                  validate_max=True, validate_min=True,
                                  can_delete=False)

def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()
    kwargs["queryset"] = Client.objects.none()
    return kwargs

def form_valid(self, form_class):
    form_class.save()

    return super().form_valid(form)

def get_context_data(self, **kwargs):
    ctx = super().get_context_data(**kwargs)
    if self.request.POST:
        ctx['inlines'] = self.form_class(self.request.POST)
    else:
        ctx['inlines'] = self.form_class()
    return ctx

def get_success_url(self):
    return reverse('client-list',
                   kwargs={'case_pk': self.kwargs['case_pk']})

我很欣赏formview实际上是用于单个表单保存的,但是当没有重复的唯一项时,它确实可以正常工作。

非常感谢

编辑:::

这是我基于函数的版本,也遇到相同的问题:

@login_required
def client(request, case_pk):
    template_name = 'clients/client_form.html'
    case = get_object_or_404(Case,
                         pk=case_pk, adviser__company__account=request.user
                         )

    formset_class = modelformset_factory(Client, ClientForm,
                                     min_num=case.number_clients,
                                     max_num=case.number_clients, extra=0,
                                     validate_max=True, validate_min=True,
                                     can_delete=False)

formset = formset_class(request.POST or None)

if request.method == 'POST':
    # check all formsets valid
    if all(form.is_valid() for form in formset):
        for f in formset:
            if f.is_valid():
                form = f.save(commit=False)
                form.case = case
                f.save()

        return HttpResponseRedirect(reverse('client-create',
                                            kwargs={'case_pk': case_pk}))

return render(request, template_name, {
    'inlines': formset,
    'case': case,
    'breadcrumbs': 'Family & Dependants'
})

客户表格:

class ClientForm(ModelForm):

class Meta:
    model = Client
    fields = ['prefix', 'first_name', 'middle_names', 'last_name',
              'gender', 'date_of_birth', 'residence', 'address_1',
              'address_2', 'address_3', 'city', 'postcode', 'telephone',
              'marital_status', 'widowed_date_of_death',
              'have_will', 'why_changing', 'existing_poa', 'dependant', ]

客户端模型很大,所以这是唯一子句:

class Meta:
    unique_together = ('case', 'first_name', 'last_name',
                       'date_of_birth', )

1 个答案:

答案 0 :(得分:0)

modelformset_factory似乎不遵守数据库级别的约束。因此,必须在保存表单之前进行检查。

他们的方法是重写BaseModelFormSet类。

此处的解决方案:Save multiple objects with a unique attribute using Django formset