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

Python 同一视图中的多个模型验证-Django 1.11,python,django,django-models,django-orm,Python,Django,Django Models,Django Orm,我正在寻找一种策略,在最终能够将它们保存到数据库中之前,验证相互关联的四个模型的键的唯一性 换句话说,我想检查键的唯一性,以便在使用Model.save()方法时,数据库中没有不一致的地方,并且只在所有唯一键都真正唯一时才使用它 以下面的视图为例,LegalPerson、Email和Phone中的字段cnpj、address和number必须是唯一的 class StoreRegistrationView(View): ''' Classe responsavel pelo ca

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

换句话说,我想检查键的唯一性,以便在使用
Model.save()
方法时,数据库中没有不一致的地方,并且只在所有唯一键都真正唯一时才使用它

以下面的视图为例,
LegalPerson
Email
Phone
中的字段cnpj、address和number必须是唯一的

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\u clean()
Model.clean()
,和
Model.validate\u 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
块中仅实例化了空白表单
AddressForm()
LegalPersonForm
(用于GET请求)。这意味着,如果表单有效,您可以在模板中看到表单错误,而不是空白表单。

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

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
块中仅实例化了空白表单
AddressForm()
LegalPersonForm
(用于GET请求)。这意味着,如果表单有效,则可以在模板中看到表单错误,而不是空白表单