J'ai essayé le contenu écrit en marge de Spécification dynamique de l'ensemble de requêtes de ModelChoiceField dans Django, donc mémo mémo.
En jouant avec Form.fields, vous pouvez modifier divers attributs d'autres champs après la création du formulaire. Est-il possible d'ajouter / supprimer le champ lui-même?
Lancez la commande shell de Django et essayez-la sur un shell interactif
Form
vide>>> from django import forms
>>> f = forms.Form()
>>> f.as_p()
''
>>> f.fields
OrderedDict()
Aucun champ n'est défini à ce stade, donc appeler ʻas_p () ne rend rien
Form.fields n'affiche que les objets ʻOrderdDict
vides
… Pour la première fois, nous savons que le type de Form.fields
est une classe appelée OrderedDict.
Form.fields
>>> f.fields['name'] = forms.CharField(label='Nom')
>>> f.as_p()
'<p><label for="id_name">Nom:</label> <input id="id_name" name="name" type="text" /></p>'
>>> f.fields
OrderedDict([('name', <django.forms.fields.CharField object at 0x00000000045E5B388>)])
Ajoutez «CharField» avec la clé «nom». Correctement rendu avec ʻas_p () `. Le contenu de «Form.fields» contient également l'objet de «CharField» avec la clé «nom».
et vérification des erreurs,
nettoyées_données`>>> f.is_valid()
Flase
>>> f.errors
{}
>>> f.cleaned_data
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Form' object has no attribute 'cleaned_data'
Puisque le champ de nom ajouté est required = True
(valeur par défaut), on s'attend à ce que ʻis_valid ()soit False, mais pour une raison quelconque
Form.errors` est vide.
Quand je l'ai recherché, si l'objet Form
n'avait pas changé la valeur de chaque champ, ou n'avait pas reçu de données
dans son argument, il créerait simplement une ʻerreurs vide et gérer
full_clean (). Il semble se terminer (
cleaning_data` n'est pas généré non plus).
Il n'y a aucune aide pour cela, alors passez l'argument data
à l'objet Form
et régénérez-le. Je vais essayer.
>>> f = forms.Form(data={})
>>> f.fields['name'] = forms.CharField(label='Nom')
>>> f.is_valid()
False
>>> f.errors
{'name': ['This field is required.']}
>>> f.cleaned_data
{}
Comme prévu, le contenu de «erreurs» contenait une erreur de vérification obligatoire pour «nom».
Un dict vide est également généré pour clean_data
.
et ʻerrors
Au début, j'ai essayé d'assigner directement un dict vide à Form.data
pour résoudre le problème de ↑, mais le résultat n'a pas changé.
Quand j'ai suivi la source de django, c'était à cause du traitement suivant au début de __init __ ()
de la classe BaseForm
, qui est le parent de la classe Form
.
forms.py
self.is_bound = data is not None or files is not None
Donc, l'implémentation de ʻis_valid` est seulement une ligne ci-dessous
forms.py
def is_valid(self):
"""
Returns True if the form has no errors. Otherwise, False. If errors are
being ignored, returns False.
"""
return self.is_bound and not bool(self.errors)
De plus, les erreurs sont définies comme des méthodes avec des décorateurs de propriété plutôt que comme des champs.
forms.py
@property
def errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors
Ainsi, il ne suffisait pas d'éditer directement les «données», et les deux processus suivants étaient nécessaires.
full_clean ()
Eh bien, si vous pensez l'utiliser comme une application Web normale, vous ne devriez pas avoir à changer les paramètres et à refaire la validation en traitant une requête ...
Il est naturel que la validation (appel de full_clean ()
) ne soit pas exécutée à chaque fois que ʻis_valid () ou ʻerrors
est accédé, mais seulement la première fois.
data
pour que la validation soit True>>> f.data = {'name':'hoge'}
>>> f.full_clean()
>>> f.is_valid()
True
>>> f.errors
{}
>>> f.cleaned_data
{'name':'hoge'}
>>> f.fields['date'] = forms.DateField(label='Date',required=False)
>>> f.as_p()
'<ul class="errorlist"><li>This field is required.</li></ul>\n<p><label for="id_name">Nom:</label> <input id="id_name" name="name" type="text" /></p>\n<p><label for="id_date">Date:</label> <input id="id_date" name="date" type="text" /></p>'
>>> f.fields
OrderedDict([('name', <django.forms.fields.CharField object at 0x00000000045E5B38>), ('date', <django.forms.fields.DateField object at 0x0000000002A3C828>)])
>>> f.full_clean()
>>> f.is_valid()
True
>>> f.errors
{}
>>> f.cleaned_data
{'date':None, 'name':'hoge'}
>>> f.data['date'] = '2014-12-04'
>>> f.full_clean()
>>> f.is_valid()
True
>>> f.errors
{}
>>> f.cleaned_data
{'date':datetime.date(2014, 12, 4), 'name':'hoge'}
Form.fields
>>> f.fields.popitem()
('date', <django.forms.fields.DateField object at 0x0000000002A3C828>)
>>> f.as_p()
'<p><label for="id_name">Nom:</label> <input id="id_name" name="name" type="text" value="hoge" /></p>'
>>> f.fields
OrderedDict([('name', <django.forms.fields.CharField object at 0x00000000045E5B38>)])
>>> f.full_clean()
>>> f.cleaned_data
{'name': 'hoge'}
>>> f.data
{'date': '2014-12-04', 'name': 'hoge'}
Form.fields
supprime l'élément avec ʻOrderedDict.popitem. LIFO si l'argument
last` est True (par défaut), LILO si False.
Cette fois, c'est vrai, donc le champ de date que j'ai ajouté plus tard a été supprimé.
… Ainsi, l'objet Form
de Django peut être ajouté / supprimé ultérieurement dans le champ lui-même.
Je pense qu'il peut répondre à des demandes telles que "Vous permettre d'ajouter librement des éléments d'entrée d'écran dans les paramètres principaux!"
Recommended Posts