同一视图中的多个模型验证 - Django 1.11

Multiple models validation in the same View - Django 1.11

我正在寻找一种策略来验证相互关联的四个模型的键的唯一性,然后才能最终将它们保存在数据库中。

换句话说,我想检查键的唯一性,这样使用Model.save()方法时数据库中不会出现不一致,只有当所有唯一键都真正唯一时才使用它.

以下图为例,cnpjaddressnumber[=29=字段]分别在LegalPersonEmailPhone中,必须是唯一的。

class StoreRegistrationView(View):
    '''
    Classe responsavel pelo cadastro de lojas
    '''
    def post(self, request):

        if request.method == 'POST':
            #import pdb; pdb.set_trace()
            form = StoreForm(request.POST)

            if form.is_valid():

                lp = LegalPerson(
                    cnpj = form.cleaned_data['cnpj'],
                    corporate_name = form.cleaned_data['corporate_name'],
                    fantasy_name = form.cleaned_data['fantasy_name'],
                    state_inscription = form.cleaned_data['state_inscription'],
                    municipal_inscription = form.cleaned_data['municipal_inscription'],
                    )

                lp.save()

                address = Address(
                    street = form.cleaned_data['street'],
                    neighborhood = form.cleaned_data['neighborhood'],
                    number = form.cleaned_data['number'],
                    complement = form.cleaned_data['complement'],
                    city = form.cleaned_data['city'],
                    estate = form.cleaned_data['estate'],
                    country = 'Brasil',
                    cep = form.cleaned_data['cep'],
                    latitude = form.cleaned_data['latitude'],
                    longitude = form.cleaned_data['longitude'],
                    person = lp,
                    )

                address.save()

                email = Email(
                    address = form.cleaned_data['email'],
                    person=lp,
                    )

                email.save()

                phone = Phone(
                    number=form.cleaned_data['phone_number'],
                    person=lp,
                    )

                phone.save()

                # Mensagem de sucesso que será disponibilizada para o usuário
                messages.success(request, 'Cadastro de loja efetuado com sucesso.')

                return redirect('importar-produtos')

        messages.warning(request, 'Erro durante o cadastro.')
        context = {
            'store_form': StoreForm(),
                }

        return render(request, 'n3oadmin/store-registration.html', context)

我一直在研究,发现 django 中的模型有一些验证方法,如 Model.full_clean()Model.clean()Model.validate_unique()

你可以参考这里设置一个唯一的字段。

https://docs.djangoproject.com/en/1.11/ref/models/fields/#unique

您应该创建多个模型表单,而不是使用常规表单。

class LegalPersonForm(forms.ModelForm):
    class Meta:
        model = LegalPerson
        fields = [...]

class = AddressForm(forms.ModelForm):
    class Meta:
        model = LegalPerson
        exclude = ['person']

然后,在您的视图和模板中使用您的模型表单。模型表单将负责验证唯一约束。

if request.method == 'POST':
    address_form = AddressForm(request.POST)
    legal_person_form = LegalPersonForm(request.POST)

    if address_form.is_valid() and legal_person_form.is_valid():
        person = legal_person_form.save()
        address = address_form.save(commit=False)
        address.person = person
        address.save()

        ...

        return redirect('importar-produtos')
else:
    address_form = AddressForm()
    legal_person_form = LegalPersonForm()

context = {
    'address_form': address_form,
    'legal_person_form': legal_person_form,
}
return render(request, 'n3oadmin/store-registration.html', context)

请注意,您可以在模型表单中排除外键字段。然后,在视图中,可以用commit=False保存,设置外键,然后保存实例。

另请注意,我们仅在 else 块(对于 GET 请求)中实例化了空白表单 AddressForm()LegalPersonForm。这意味着如果表单有效,您将在模板中看到表单错误而不是空白表单。