Django сохранение моделиformset_factory - PullRequest
0 голосов
/ 06 сентября 2018

При сохранении набора форм он не проверяет и не учитывает поля модели, которые я сделал уникальными, и поэтому выдает ошибку целостности, если я намеренно продублирую поля для проверки.

Я предполагаю, что сами наборы форм проверяются правильно, но поскольку уникальное поле - это то, что я должен назначить во время процесса сохранения (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 на самом деле должен использоваться для сохранения одной формы, но на самом деле это работает правильно, если нет дублирующихся уникальных элементов.

Большое спасибо

EDIT :::

Это моя версия на основе функций, которая также страдает от той же проблемы:

@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 голосов
/ 06 сентября 2018

modelformset_factory не соответствует ограничениям уровня базы данных. Поэтому проверку необходимо выполнить перед сохранением формы.

Они могут сделать это путем переопределения класса BaseModelFormSet.

Решение здесь: Сохранение нескольких объектов с уникальным атрибутом, используя набор форм Django

...