Se eu tiver um formulário Django, como:
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
E eu chamo o método as_table () de uma instância deste formulário, o Django irá renderizar os campos na mesma ordem especificada acima.
Minha pergunta é como o Django sabe a ordem em que as variáveis de classe foram definidas?
(Além disso, como faço para substituir essa ordem, por exemplo, quando quero adicionar um campo do método init da classe ?)
fonte
As novidades no Django 1.9 são Form.field_order e Form.order_fields () .
fonte
Eu fui em frente e respondi minha própria pergunta. Aqui está a resposta para referência futura:
No Django
form.py
faz alguma magia negra usando o__new__
método para carregar as variáveis de sua classeself.fields
na ordem definida na classe.self.fields
é umaSortedDict
instância do Django (definida emdatastructures.py
).Então, para substituir isso, digamos no meu exemplo que você quisesse que o remetente viesse primeiro, mas precisava adicioná-lo em um método init , você faria:
fonte
self.fields.insert( 0, 'sender', self.fields['sender'] )
Os campos são listados na ordem em que são definidos em ModelClass._meta.fields. Mas se você quiser mudar a ordem no Form, você pode fazer usando a função keyOrder. Por exemplo :
fonte
Com Django> = 1.7, você deve modificar
ContactForm.base_fields
conforme abaixo:Este truque é usado no Django Admin
PasswordChangeForm
: Fonte no Githubfonte
PasswordChangeForm
mudou a ordem dos campos, então seu exemplo acabou sendo muito útil para mim. Parece que é porquebase_fields
não é transportado para a subclasse. A solução parece estar dizendoPasswordChangeFormSubclass.base_fields = PasswordChangeForm.base_fields
após a definição de `PasswordChangeFormSubclassContactForm.base_fields[k]
ao construir o dicionário ordenado. Há um erro de digitação na resposta, vou editarOs campos do formulário possuem um atributo para a ordem de criação, chamado
creation_counter
..fields
attribute é um dicionário, portanto, adicionar ao dicionário e alterarcreation_counter
atributos em todos os campos para refletir a nova ordem deve ser suficiente (nunca tentei isso, no entanto).fonte
Use um contador na classe Field. Classifique por esse contador:
Resultado:
fonte
A partir do Django 1.7, os formulários usam OrderedDict, que não suporta o operador append. Então você tem que reconstruir o dicionário do zero ...
fonte
Para referência futura: as coisas mudaram um pouco desde as novas formas. Esta é uma maneira de reordenar campos de classes de formulário básicas sobre as quais você não tem controle:
Além disso, há um pouco de documentação sobre SortedDict que pode ser
base_fields
usado aqui: http://code.djangoproject.com/wiki/SortedDictfonte
Se
fields = '__all__'
:ou
exclude
são usados:Então o Django referencia a ordem dos campos conforme definido no modelo . Isso simplesmente me pegou, então pensei em mencionar isso. É referenciado na documentação ModelForm :
fonte
A maneira mais fácil de solicitar campos nos formulários django 1.9 é usar
field_order
em seu formulário Form.field_orderAqui está um pequeno exemplo
Isso mostrará tudo na ordem especificada em
field_order
dict.fonte
Usar
fields
naMeta
aula interna é o que funcionou para mim emDjango==1.6.5
:Tão simples como isso.
fonte
django.forms
não funcionaEu usei isso para mover campos sobre:
Isso funciona no 1.5 e estou razoavelmente certo de que ainda funciona nas versões mais recentes.
fonte
Tem a ver com a meta classe que é usada na definição da classe do formulário. Acho que mantém uma lista interna dos campos e se você inserir no meio da lista pode funcionar. Já faz um tempo desde que eu olhei esse código.
fonte