2012-03-21 2 views
4

J'essaie de déplacer toutes les validations liées à la logique métier vers des modèles, au lieu de les laisser dans des formulaires. Mais ici, j'ai une situation difficile, pour laquelle j'aime consulter la communauté SO.Est-ce que les modèles django offrent quelque chose de similaire aux formulaires 'clean_ <fieldname>()?

Dans ma SignupForm (un formulaire de modèle), j'ai la validation spécifique au champ suivante pour m'assurer que l'email d'entrée n'existe pas déjà.

def clean_email(self): 
    email = self.cleaned_data['email'] 

    if ExtendedUser.objects.filter(email=email).exists(): 
     raise ValidationError('This email address already exists.') 
    return email 

Si je devais passer cette validation aux modèles, selon le document officiel, je le mettrais dans clean() du modèle correspondant, ExtendedUser. Mais le document mentionne également les éléments suivants:

Toute exception ValidationError soulevées par Model.clean() seront stockés une erreur clé spéciale clé de dictionnaire, NON_FIELD_ERRORS, qui est utilisé pour les erreurs qui sont liées à l'ensemble modèle au lieu de un champ

spécifique qui signifie, avec clean(), je ne peux pas associer les erreurs soulevées à partir avec des domaines spécifiques. Je me demandais si les modèles offrent quelque chose de similaire aux formes clean_<fieldname>(). Si non, où mettriez-vous cette logique de validation et pourquoi?

+0

Isn » t cette logique liée à la forme si? Pourquoi pensez-vous qu'il serait préférable pour elle de vivre dans le modèle? Ce serait l'utilisation prévue de modelforms dans django à mon avis. – vascop

+0

@VascoP - Je veux juste centraliser toute ma logique métier dans les modèles. Pour l'un, c'est plus organisé en termes de design. Et conceptuellement, je pense qu'il est logique pour la validation de vivre dans des modèles. En outre, il a l'avantage de partager la même validation lorsque j'ai plusieurs formulaires de modèle basés sur le même modèle. – tamakisquare

+2

Vous pouvez également hériter d'une forme de modèle plus générale associée à un modèle donné et avoir des sous-modèles pour chaque forme différente. – vascop

Répondre

3

Vous pouvez convertir votre méthode propre en validator et l'inclure lorsque vous déclarez le champ.

Une autre option consiste à sous-classer le champ de modèle et à remplacer sa méthode propre.

Cependant, il n'existe aucun équivalent direct pour définir les méthodes clean_<field name> comme vous pouvez le faire pour les formulaires. Vous ne pouvez même pas affecter des erreurs à des champs individuels,

1

Comme indiqué dans le commentaire, je crois que vous devriez gérer cette validation au niveau du modèle. Si vous vous sentez toujours comme il serait préférable de le faire plus près du modèle, et comme ils ne peuvent pas être modifiés, je vous conseille un changement directement au niveau db:

ALTER TABLE auth_user ADD UNIQUE (email) 

Quelle est la mauvaise façon de ajoutez la contrainte unique=True au modèle User sans authentification de correctif de singe. Comme demandé, je pense qu'un bon moyen de personnaliser les différents formulaires devrait être fait en héritant d'un modelform de base. Un bon exemple de ceci se trouve dans django-registration. La seule différence est qu'au lieu de la forme mère héritant de forms.Form vous faire une ModelForm:

class MyBaseModelForm(ModelForm): 
    class Meta: 
     model = MyModel 

Vous pouvez ensuite hériter de lui et de faire différentes formes de ce modèle de base:

class OtherFormWithCustomClean(MyBaseModelForm): 
    def clean_email(self): 
     email = self.cleaned_data['email'] 
     if ExtendedUser.objects.filter(email=email).exists(): 
      raise ValidationError('This email address already exists.') 
    return email 
Questions connexes