Si j'ai un formulaire Django tel que:
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
Et j'appelle la méthode as_table () d'une instance de ce formulaire, Django rendra les champs dans le même ordre que spécifié ci-dessus.
Ma question est de savoir comment Django connaît l'ordre dans lequel les variables de classe ont été définies?
(Comment puis-je remplacer cet ordre, par exemple lorsque je veux ajouter un champ à partir de la méthode init de la classe ?)
Les nouveautés de Django 1.9 sont Form.field_order et Form.order_fields () .
la source
Je suis allé de l'avant et j'ai répondu à ma propre question. Voici la réponse pour référence future:
Dans Django
form.py
fait de la magie noire en utilisant la__new__
méthode pour charger finalement vos variables de classeself.fields
dans l'ordre défini dans la classe.self.fields
est uneSortedDict
instance Django (définie dansdatastructures.py
).Donc, pour remplacer cela, disons dans mon exemple que vous vouliez que l'expéditeur vienne en premier mais que vous deviez l'ajouter dans une méthode init , vous feriez:
la source
self.fields.insert( 0, 'sender', self.fields['sender'] )
Les champs sont répertoriés dans l'ordre dans lequel ils sont définis dans ModelClass._meta.fields. Mais si vous souhaitez modifier l'ordre dans Form, vous pouvez le faire en utilisant la fonction keyOrder. Par exemple :
la source
Avec Django> = 1.7, vous devez modifier
ContactForm.base_fields
comme ci-dessous:Cette astuce est utilisée dans Django Admin
PasswordChangeForm
: Source sur Githubla source
PasswordChangeForm
changé l'ordre des champs, donc votre exemple s'est avéré être très utile pour moi. Il semble que ce soit parce qu'ilbase_fields
n'est pas transféré à la sous-classe. La solution semble être de direPasswordChangeFormSubclass.base_fields = PasswordChangeForm.base_fields
après la définition de `PasswordChangeFormSubclassContactForm.base_fields[k]
lors de la construction du dict commandé. Il y a une faute de frappe dans la réponse, je vais modifierLes champs de formulaire ont un attribut pour l'ordre de création, appelé
creation_counter
..fields
L'attribut est un dictionnaire, donc un simple ajout au dictionnaire et la modification descreation_counter
attributs dans tous les champs pour refléter le nouvel ordre devrait suffire (jamais essayé cela, cependant).la source
Utilisez un compteur dans la classe Field. Trier par ce compteur:
Production:
la source
Depuis les formulaires Django 1.7, utilisez OrderedDict qui ne prend pas en charge l'opérateur d'ajout. Il faut donc reconstruire le dictionnaire à partir de zéro ...
la source
Pour référence future: les choses ont un peu changé depuis les nouvelles formes. C'est une façon de réorganiser les champs des classes de formulaire de base sur lesquelles vous n'avez aucun contrôle:
De plus, il y a un peu de documentation sur le SortedDict qui
base_fields
utilise ici: http://code.djangoproject.com/wiki/SortedDictla source
Si l'un ou l'autre
fields = '__all__'
:ou
exclude
sont utilisés:Django référence ensuite l'ordre des champs tel que défini dans le modèle . Cela m'a juste surpris, alors j'ai pensé le mentionner. Il est référencé dans la documentation ModelForm :
la source
La manière la plus simple de classer les champs dans les formulaires django 1.9 est d'utiliser
field_order
dans votre formulaire Form.field_orderVoici un petit exemple
Cela affichera tout dans l'ordre que vous avez spécifié dans
field_order
dict.la source
L'utilisation
fields
enMeta
classe interne est ce qui a fonctionné pour moiDjango==1.6.5
:Aussi simple que cela.
la source
django.forms
ne fonctionne pasJ'ai utilisé ceci pour déplacer des champs sur:
Cela fonctionne dans la version 1.5 et je suis raisonnablement sûr que cela fonctionne toujours dans les versions plus récentes.
la source
Cela a à voir avec la classe méta utilisée pour définir la classe de formulaire. Je pense qu'il garde une liste interne des champs et si vous insérez au milieu de la liste, cela pourrait fonctionner. Cela fait un moment que j'ai regardé ce code.
la source