Génère une erreur de validation dans la méthode save d'un modèle dans Django

Je ne suis pas sûr de savoir comment générer correctement une erreur de validation dans la méthode de sauvegarde d'un modèle et renvoyer un message clair à l'utilisateur.

, Fondamentalement, je veux savoir comment chaque partie de "si" la fin de celui où je veux soulever l'erreur et celui où il enregistre:

def save(self, *args, **kwargs):
    if not good_enough_to_be_saved:
        raise ValidationError
    else:
        super(Model, self).save(*args, **kwargs)

Ensuite, je veux savoir quoi faire pour envoyer une erreur de validation qui dit exactement à l'utilisateur ce qui ne va pas comme celui que Django renvoie automatiquement si par exemple une valeur n'est pas unique. Je suis à l'aide d'un (ModelForm) et régler tout à partir du modèle.

42
demandé sur Mateusz Piotrowski 0000-00-00 00:00:00

2 réponses

La plupart des vues Django, par exemple L'administrateur Django ne sera pas en mesure de gérer une erreur de validation dans la méthode save, de sorte que vos utilisateurs obtiendront 500 erreurs.

Vous devriez faire la validation sur le formulaire de modèle ou sur le modèle, et soulever ValidationError là. Ensuite, appelez save() uniquement si les données du formulaire de modèle sont "assez bonnes pour enregistrer".

35
répondu Alasdair 2012-01-07 16:18:57

Bastian, je vous explique mon modèle de code, j'espère que cela vous aidera:

Depuis django 1.2 il est capable d'écrire le code de validation sur le modèle. Lorsque nous travaillons avec modelforms, instance.full_clean() est appelée lors de la validation du formulaire.

Dans chaque modèle, j'écrase la méthode clean() avec une fonction personnalisée (cette méthode est automatiquement appelée à partir de full_clean () lors de la validation de modelform):

from django.db import models

class Issue(models.Model):
    ....
    def clean(self): 
        rules.Issue_clean(self)  #<-- custom function invocation

from issues import rules
rules.connect()

Puis dans le fichier rules.py j'écris des règles de bussiness. Aussi je me connecte pre_save() à mon fonction personnalisée pour empêcher de sauvegarder un modèle avec un mauvais état:

Des questions.problème d'importation de Modèles

def connect():    
    from django.db.models.signals import post_save, pre_save, pre_delete
    #issues 
    pre_save.connect(Issue_pre_save, sender = Incidencia ) 
    post_save.connect(Issue_post_save, sender = Incidencia )
    pre_delete.connect(Issue_pre_delete, sender= Incidencia) 

def Incidencia_clean( instance ):    #<-- custom function 
    import datetime as dt    
    errors = {}

    #dia i hora sempre informats     
    if not instance.dia_incidencia:   #<-- business rules
        errors.setdefault('dia_incidencia',[]).append(u'Data missing: ...')

    #dia i hora sempre informats     
    if not  instance.franja_incidencia: 
        errors.setdefault('franja_incidencia',[]).append(u'Falten Dades: ...')

    #Només es poden posar incidències més ennlà de 7 dies 
    if instance.dia_incidencia < ( dt.date.today() + dt.timedelta( days = -7) ): 
        errors.setdefault('dia_incidencia 1',[]).append(u'''blah blah error desc)''')

    #No incidències al futur. 
    if instance.getDate() > datetime.now(): 
        errors.setdefault('dia_incidencia 2',[]).append(u'''Encara no pots ....''') 
    ... 

    if len( errors ) > 0: 
        raise ValidationError(errors)  #<-- raising errors

def Issue_pre_save(sender, instance, **kwargs): 
    instance.clean()     #<-- custom function invocation

Ensuite, modelform appelle la méthode clean du modèle et ma fonction custon vérifie un bon état ou déclenche une erreur gérée par model form.

Pour afficher les erreurs sur le formulaire, vous devez mentionner sur le formulaire modèle:

{% if form.non_field_errors %}
      {% for error in form.non_field_errors %}
        {{error}}
      {% endfor %}
{% endif %}  

La raison en est que les erreurs de validation du modèle sont liées à l'entrée du dictionnaire d'erreur non_field_errors.

Lorsque vous enregistrez ou supprimez un modèle de formulaire, vous devez vous souvenir qu'une erreur peut être soulevée:

try:
    issue.delete()
except ValidationError, e:
    import itertools
    errors = list( itertools.chain( *e.message_dict.values() ) )

En outre, vous pouvez ajouter des erreurs à un dictionnaire de formulaire sur No modelforms:

    try:
        #provoco els errors per mostrar-los igualment al formulari.
        issue.clean()
    except ValidationError, e:
        form._errors = {}
        for _, v in e.message_dict.items():
            form._errors.setdefault(NON_FIELD_ERRORS, []).extend(  v  )

Rappelez-vous que ce code n'est pas exécuté sur la méthode save (): notez que full_clean () ne sera pas appelé automatiquement lorsque vous appelez la méthode save () de votre modèle, ni à la suite de la validation de ModelForm. Ensuite, vous pouvez ajouter des erreurs à un dictionnaire de formulaire sur no modelforms :

    try:
        #provoco els errors per mostrar-los igualment al formulari.
        issue.clean()
    except ValidationError, e:
        form._errors = {}
        for _, v in e.message_dict.items():
            form._errors.setdefault(NON_FIELD_ERRORS, []).extend(  v  )
22
répondu dani herrera 2012-01-07 19:49:05