J'ai ce modèle que je montre dans la page d'administration:
class Dog(models.Model):
bark_volume = models.DecimalField(...
unladen_speed = models.DecimalField(...
def clean(self):
if self.bark_volume < 5:
raise ValidationError("must be louder!")
Comme vous pouvez le voir, j'ai mis une validation sur le modèle. Mais ce que je veux, c'est que la page d'administration affiche l'erreur à côté du champ bark_volume au lieu d'une erreur générale telle qu'elle est maintenant. Existe-t-il un moyen de spécifier sur quel champ la validation échoue?
Merci d'avance.
OK, je l'ai compris à partir de cette réponse .
Vous devez faire quelque chose comme ça:
class Dog(models.Model):
bark_volume = models.DecimalField(...
unladen_speed = models.DecimalField(...
def clean_fields(self):
if self.bark_volume < 5:
raise ValidationError({'bark_volume': ["Must be louder!",]})
class Dog(models.Model):
bark_volume = models.DecimalField(...
unladen_speed = models.DecimalField(...
def clean(self):
if self.bark_volume < 5:
if not self._errors.has_key('bark_volume'):
from Django.forms.util import ErrorList
self._errors['bark_volume'] = ErrorList()
self._errors['bark_volume'].append('must be louder!')
Cela fonctionne au moins sur les formulaires. Je ne l'ai jamais essayé sur le modèle lui-même, mais la méthodologie devrait être la même. Cependant, à partir des documents Django:
Lorsque vous utilisez un ModelForm, l'appel à is_valid () effectuera ces étapes de validation pour tous les champs inclus dans le formulaire. (Voir la documentation ModelForm pour plus d'informations.) Vous ne devez appeler la méthode full_clean () d'un modèle que si vous prévoyez de gérer vous-même les erreurs de validation ou si vous avez exclu des champs du ModelForm qui nécessitent une validation.
Et...
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 ModelForm. Vous devrez l'appeler manuellement lorsque vous souhaitez exécuter la validation du modèle en dehors d'un ModelForm.
Donc, fondamentalement, à moins que vous n'ayez une très bonne raison de nettoyer le champ sur le modèle, vous devez le faire sur le formulaire à la place. Le code pour cela ressemblerait à:
class DogForm(forms.ModelForm):
def clean(self):
bark_volume = self.cleaned_data.get('bark_volume')
if bark_volume < 5:
if not self._errors.has_key('bark_volume'):
from Django.forms.util import ErrorList
self._errors['bark_volume'] = ErrorList()
self._errors['bark_volume'].append('must be louder!')
return self.cleaned_data
Et cela fonctionnera, c'est sûr.
À noter pour tous ceux qui pourraient rencontrer cela avec une version plus récente de Django - la méthode clean_fields de la réponse acceptée nécessite maintenant un paramètre "exclude". Aussi - je crois que la réponse acceptée est également manquante un appel à sa super fonction. Le code final que j'ai utilisé était:
def clean_fields(self, exclude=None):
super(Model, self).clean_fields(exclude)
if self.field_name and not self.field_name_required:
raise ValidationError({'field_name_required':["You selected a field, so field_name_required is required"]})
Utiliser un clean_
méthode spécifique au champ:
class DogForm(forms.ModelForm):
class Meta:
model = Dog
def clean_bark_volume(self):
if self.cleaned_data['bark_volume'] < 5:
raise ValidationError("must be louder!")
Voir le clean<fieldname>
partie de la page Validation du formulaire . Assurez-vous également d'utiliser cleaned_data
au lieu du champ de formulaire lui-même; ces derniers peuvent avoir d'anciennes données. Enfin, faites-le sur le formulaire et non sur le modèle.
La manière la plus simple de valider ce cas particulier serait:
from Django.core.validators import MinValueValidator
from Django.utils.translation import ugettext_lazy as _
class Dog(models.Model):
bark_volume = models.DecimalField(
..., validators=[MinValueValidator(5, message=_("Must be louder!"))]
Documentation de Django sur les validateurs: https://docs.djangoproject.com/en/dev/ref/validators/
en abrégé, à partir des documents Django :
def clean(self):
data = self.cleaned_data
subject = data.get("subject")
if subject and "help" not in subject:
msg = "Must put 'help' in subject."
self.add_error('subject', msg)
return data