Django保存modelformset_factory

问题描述 投票:0回答:1

保存formset时,它没有验证并尊重我使其独特的模型字段,因此如果我故意复制字段以测试它,则会呈现完整性错误。

我的猜测是表单集本身正确验证,但由于唯一字段是我必须在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', )
django formview
1个回答
0
投票

modelformset_factory似乎不尊重数据库级别约束。因此,必须在保存表单之前完成检查。

他们这样做的方法是重写BaseModelFormSet类。

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

© www.soinside.com 2019 - 2024. All rights reserved.