2010-03-05 6 views
2

Je dois ajouter une validation supplémentaire à mon champ DateField dans Admin pour m'assurer que la date donnée est dans le futur. Je n'ai aucune expérience dans une telle chose, alors voici ce que j'ai fait. 1) J'ai créé champ de formulaire personnalisé et validation ajoutai:ne peut pas remplacer le modèle d'administrateur par défaut formulaire django

class PastDateField(forms.DateField): 
    def clean(self, value): 
    """Validates if only date is in the past 
    """ 
     if not value: 
      raise forms.ValidationError('Plase enter the date') 
     if value > datetime.now(): 
      raise forms.ValidationError('The date should be in the past, not in future') 
     return value 

2) Ensuite, j'ai ajouté sous forme de modèle personnalisé:

class CustomNewsItemAdminForm(forms.ModelForm): 
    title = forms.CharField(max_length=100) 
    body = forms.CharField(widget=forms.Textarea) 
    date = PastDateField() 
    region = forms.ModelChoiceField(Region.objects) 

3) Et voici comment je me suis inscrit admin:

class NewsItemAdmin(admin.ModelAdmin): 
    form = CustomNewsItemAdminForm 

    def queryset(self, request): 
     return NewsItem.objects.all() 

admin.site.register(NewsItem, NewsItemAdmin) 

Le résultat de ceci est que ma forme admin 1) Indique le terrain que je ne l'ai pas spécifié sous forme d'administration personnalisée 2) Lacks JavaScr ipt calendrier pour le champ datetime

Il est assez évident pour moi que je fais quelque chose de mal, mais je n'ai trouvé aucun exemple pertinent à mes besoins comme je suis un noob. Quelle est la meilleure façon d'ajouter une validation personnalisée au champ datetime sans gâcher les choses?

EDIT: Merci beaucoup à Brian Luft et Daniel Roseman pour les bonnes réponses! Pour ce poste utile pour quelqu'un face au même problème est le code qui en résulte ici:

class CustomNewsItemAdminForm(forms.ModelForm): 
    class Meta: 
     model = NewsItem 

    def clean_date(self): 
     """Validates if only date is in the past 
     """ 
     date = self.cleaned_data["date"] 
     if date is None: 
      raise forms.ValidationError('Plase enter the date') 
     if date > datetime.now().date(): 
      raise forms.ValidationError('The date should be in the past, not in future') 
     return self.cleaned_data["date"] 

class NewsItemAdmin(admin.ModelAdmin): 
    form = CustomNewsItemAdminForm 

    def queryset(self, request): 
     return NewsItem.objects.all() 

admin.site.register(NewsItem, NewsItemAdmin) 
+1

Avez-vous ajouté la déclaration de modèle Meta à votre formulaire (et l'avez juste laissé à côté de l'extrait)? Vous n'avez probablement pas besoin de déclarer les champs sur votre formulaire et devez utiliser l'option 'fields' ou 'exclude' à la place. Enfin, vous pouvez essayer de quitter la date comme un champ DateField normal et fournir une méthode clean_date sur le formulaire lui-même: http://docs.djangoproject.com/fr/1.1/ref/contrib/admin/#adding-custom-validation-to -the-admin http://docs.djangoproject.com/fr/1.1/topics/forms/modelforms/#overriding-modelform-clean-method Pouvez-vous aussi coller dans votre définition de modèle? –

Répondre

2

Tout d'abord, les déclarations de champs explicitement sur une ModelForm - que ce soit dans ou hors de l'administrateur - ne signifie pas que les autres champs ne seront pas être affichée. Vous devez définir les tuples fields ou exclude dans la classe interne Meta du formulaire. Si les autres champs sont tous les champs par défaut, vous pouvez simplement déclarer celui que vous remplacez. Deuxièmement, si vous souhaitez que votre champ personnalisé utilise le javascript, vous devez utiliser le bon widget, à savoir django.contrib.admin.widgets.AdminDateWidget. Cependant, il existe un moyen beaucoup plus simple de le faire, qui n'est pas de définir un champ personnalisé, mais de définir une méthode clean_date sur le formulaire lui-même.

Questions connexes