同一视图中的多个模型验证 - Django 1.11
Multiple models validation in the same View - Django 1.11
我正在寻找一种策略来验证相互关联的四个模型的键的唯一性,然后才能最终将它们保存在数据库中。
换句话说,我想检查键的唯一性,这样使用Model.save()
方法时数据库中不会出现不一致,只有当所有唯一键都真正唯一时才使用它.
以下图为例,cnpj、address、number[=29=字段]分别在LegalPerson
、Email
和Phone
中,必须是唯一的。
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
。这意味着如果表单有效,您将在模板中看到表单错误而不是空白表单。
我正在寻找一种策略来验证相互关联的四个模型的键的唯一性,然后才能最终将它们保存在数据库中。
换句话说,我想检查键的唯一性,这样使用Model.save()
方法时数据库中不会出现不一致,只有当所有唯一键都真正唯一时才使用它.
以下图为例,cnpj、address、number[=29=字段]分别在LegalPerson
、Email
和Phone
中,必须是唯一的。
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
。这意味着如果表单有效,您将在模板中看到表单错误而不是空白表单。