I need to reorder the fields in a modelform that came from another base class. Couldn't find a solution to that. "Address" in the snippet below always show up at the beginning in the HTML template. How can I move it further down with the rendered template? Thanks in advance.
class Address:
street= ...
city= ...
class Customer(Address):
name = ...
...
class CustomerForm(ModelForm):
def __init__(...)
super(CustomerForm, self).__init__(*args, **kw)
self.fields.keyOrder=[
'name',
'Address', #<-- I want "Address" appear after the name in my template
#<-- This obviously is not the right code.
class Meta:
model = Customer
-P
In Django 1.9 they add new argument to Form class Now you can change the order by defining field_order for example adding two fields to userena application form:
class SignupFormExtra(SignupForm):
"""
A form to demonstrate how to add extra fields to the signup form, in this
case adding the first and last name.
"""
first_name = forms.CharField(label=_(u'First name'),
max_length=30,
required=False)
last_name = forms.CharField(label=_(u'Last name'),
max_length=30,
required=False)
field_order=['first_name','last_name']
You can use it to any form that inherit class Form.
By default Form.field_order=None, which retains the order in which you define the fields in your form class. If field_order is a list of field names, the fields are ordered as specified by the list and remaining fields are appended according to the default order.
Re-ordering is quite tedious:
# django's SortedDict stores ordering of its fields in this list-type attribute:
keyorder = self.fields.keyOrder
# Remove fields which we want to displace:
keyorder.remove('street')
keyorder.remove('city')
# Get position where we want them to put in:
i = keyorder.index('name') + 1
# Insert items back into the list:
keyorder[i:i] = ['city', 'street']
probably better just to list all the fields again in proper order:
class MyForm(ModelForm):
class Meta:
model=Customer
fields=[..., 'name', 'street', 'city', ...]
from django import forms
class CustomForm(forms.Form):
ORDER = ('field1', 'field2', 'field3')
def __init__(self, *args, **kwargs):
super(CustomForm, self).__init__(*args, **kwargs)
fields = OrderedDict()
for key in self.ORDER:
fields[key] = self.fields.pop(key)
self.fields = fields
When we upgraded to Django 1.7 Skyjur's use of .keyOrder
stopped working (Django is using collections.OrderedDict
now instead). As a result, I had to find a work-around and this is what appears to be working for me:
from collections import OrderedDict
...
class MyForm(forms
def __init__(self, *args, **kwargs):
fields = OrderedDict()
for key in ("my_preferred_first_field", "my_preferred_second_field"):
fields[key] = self.fields.pop(key)
for key, value in self.fields.items():
fields[key] = value
self.fields = fields
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With