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.
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".
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 )