web-dev-qa-db-fra.com

Comment accéder aux données lorsque form.is_valid () est faux

Lorsque j'ai un formulaire Django valide, je peux accéder aux données avec form.cleaned_data. Mais comment puis-je obtenir les données entrées par un utilisateur lorsque le formulaire n'est pas valide, c'est-à-dire que form.is_valid est faux.

J'essaie d'accéder aux formulaires dans un ensemble de formulaires, donc form.data semble me donner juste un gâchis.

47
Greg

Vous pouvez utiliser

form.data['field_name']

De cette façon, vous obtenez la valeur brute affectée au champ.

42
Dmitry Risenberg

Voir http://docs.djangoproject.com/en/dev/ref/forms/validation/#ref-forms-validation

Deuxièmement, une fois que nous avons décidé que les données combinées dans les deux champs que nous considérons ne sont pas valides, nous devons nous rappeler de les supprimer des données nettoyées.

En fait, Django effacera actuellement complètement le dictionnaire cleaner_data s'il y a des erreurs dans le formulaire. Cependant, ce comportement peut changer à l'avenir, donc ce n'est pas une mauvaise idée de nettoyer après vous en premier lieu.

Les données d'origine sont toujours disponibles dans request.POST.


Un commentaire suggère que le but est de faire quelque chose qui ressemble à une validation plus sophistiquée au niveau du terrain.

Chaque champ reçoit les données non validées et renvoie les données valides ou déclenche une exception.

Dans chaque domaine, tout type de validation peut être effectué sur le contenu d'origine.

17
S.Lott

Je luttais avec un problème similaire et j'ai rencontré une grande discussion ici: https://code.djangoproject.com/ticket/10427

Ce n'est pas du tout bien documenté, mais pour un formulaire en direct, vous pouvez afficher la valeur d'un champ - tel que vu par les widgets/utilisateurs - avec les éléments suivants:

form_name['field_name'].value()
13
Sam

J'ai plusieurs méthodes. Tout ce que vous pouvez choisir.

Je suppose que le formulaire est comme ci-dessous:

class SignupForm(forms.Form):
    email = forms.CharField(label='email')
    password = forms.CharField(label='password',
                               widget=forms.PasswordInput)

1-1. Obtenir à partir de request

def signup(req):
    if req.method == 'POST':
        email = req.POST.get('email', '')
        password = req.POST.get('password', '')

2-1. Obtenir le raw value affecté au champ et retourne la valeur de l'attribut data du champ

def signup(req):
    if req.method == 'POST':
        ...
        sf = SignupForm(req.POST)
        email = sf["email"].data
        password = sf["password"].data
        ...

2-2. Récupère la valeur brute affectée au champ et renvoie la valeur de l'attribut value du champ

def signup(req):
    if req.method == 'POST':
        ...
        sf = SignupForm(req.POST)
        email = sf["email"].value()
        password = sf["password"].value()
        ...

2-3. Obtenez le dictionary affecté aux champs

def signup(req):
    if req.method == 'POST':
        ...
        sf = SignupForm(req.POST)
        # print sf.data
        # <QueryDict: {u'csrfmiddlewaretoken': [u'U0M9skekfcZiyk0DhlLVV1HssoLD6SGv'], u'password': [u''], u'email': [u'hello']}>
        email = sf.data.get("email", '')
        password = sf.data.get("password", '')
        ...
8
Burger King

Vous pouvez utiliser ce modèle:

class MyForm(forms.Form):
    ...
    def clean(self):
        self.saved_data=self.cleaned_data
        return self.cleaned_data

Dans votre code:

if form.is_valid():
    form.save()
    return Django.http.HttpResponseRedirect(...)
if form.is_bound:
    form.saved_data['....'] # cleaned_data does not exist any more, but saved_data does.

L'utilisation de form.data n'est pas une bonne solution. Les raisons:

  • Si le formulaire a un préfixe, les clés du dictionnaire seront préfixées avec ce préfixe.
  • Les données dans form.data ne sont pas nettoyées: il n'y a que des valeurs de chaîne.
5
guettli

J'ai rencontré un problème similaire en utilisant un formset. Dans mon exemple, je voulais que l'utilisateur sélectionne un 1er choix avant un 2e choix, mais si le 1er choix a rencontré une autre erreur, l'erreur 'sélectionner le 1er choix avant le 2e' a également été affichée.

Pour récupérer les données non nettoyées du 1er champ, j'ai utilisé cela dans la méthode propre du champ de formulaire:

dirty_rc1 = self.data[self.prefix + '-reg_choice_1']

Ensuite, j'ai pu tester la présence de données dans ce domaine:

if not dirty_rc1:
    raise ValidationError('Make a first choice before second')

J'espère que cela t'aides!

3
Dashdrum

Vous accédez aux données à partir de la méthode clean () du champ ou de la méthode clean () du formulaire. clean () est la fonction qui détermine si le formulaire est valide ou non. Il est appelé lorsque is_valid () est appelé. Dans le formulaire propre (), vous avez le cleaned_data liste quand vous pouvez parcourir le code personnalisé pour vous assurer que tout est extrait. Dans le widget, vous avez également un clean (), mais il utilise une seule variable passée. Pour accéder à la méthode clean () du champ, vous devrez le sous-classer. par exemple.:

class BlankIntField(forms.IntegerField):
    def clean(self, value):
        if not value:
            value = 0
        return int(value)

Si vous voulez un IntField qui ne s'étouffe pas sur une valeur vide, par exemple, vous utiliseriez ce qui précède.

clean () sur une sorte d'œuvres comme celle-ci:

def clean(self):
    if self.cleaned_data.get('total',-1) <= 0.0:
        raise forms.ValidationError("'Total must be positive")
    return self.cleaned_data

Vous pouvez également avoir une fonction clean_FIELD () pour chaque champ afin que vous puissiez valider chaque champ individuellement (après l'appel de clean () du champ)

1
priestc