2017-08-18 1 views
0

Je cherche une stratégie pour valider l'unicité des clés de quatre modèles qui ont des relations les uns avec les autres avant de pouvoir enfin les sauvegarder dans la base de données. En d'autres termes, je voudrais vérifier l'unicité des clés afin qu'il n'y ait pas d'incohérence dans la base de données lors de l'utilisation de la méthode Model.save(), et ne l'utiliser que lorsque toutes les clés uniques sont vraiment uniques.Validation de plusieurs modèles dans le même View - Django 1.11

Suite à la vue ci-dessous à titre d'exemple, les champs CNPJ, adresse et nombre respectivement LegalPerson, Email et Phone, doit être unique.

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) 

J'ai fait des recherches, et a constaté que les modèles de django ont des méthodes comme la validation Model.full_clean(), Model.clean() et Model.validate_unique().

Répondre

1

Au lieu d'utiliser une forme régulière, vous devez créer les modèles de formulaires multiples.

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

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

Ensuite, utilisez vos formulaires de modèle dans votre vue et votre modèle. Les formulaires du modèle se chargeront de valider les contraintes uniques.

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) 

Notez que vous pouvez exclure des champs de clé étrangère dans le formulaire de modèle. Ensuite, dans la vue, vous pouvez enregistrer avec commit=False, définir la clé étrangère, puis enregistrer l'instance.

Notez également que nous avons seulement instancié les formulaires vierges AddressForm() et LegalPersonForm dans le bloc else (pour les requêtes GET). Cela signifie que si le formulaire est valide, vous pouvez voir les erreurs de formulaire dans le modèle au lieu d'un formulaire vierge.