trying to alter order of fields in admin ModelForm
.
Bellow is my attempt, however order is kept unchanged. Added fields oi_number
and vat_number
are rendered at the end besides they are not at the end in self.fields
SortedDict dictionary.
class ContactAdminForm(forms.ModelForm):
oi_number = fields_for_model(OrganizationExtra)['oi_number']
vat_number = fields_for_model(OrganizationExtra)['vat_number']
# fields = ('organization', 'oi_number', 'vat_number')
# ^^^ this won't affect fields order either
class Meta:
model = Organization
def __init__(self, *args, **kwargs):
super(ContactAdminForm, self).__init__(*args, **kwargs)
try:
org_ix = self.fields.keyOrder.index('organization')
self.fields.keyOrder.insert(org_ix+1, self.fields.keyOrder[-2])
self.fields.keyOrder.insert(org_ix+2, self.fields.keyOrder[-1])
del self.fields.keyOrder[-2:]
except ValueError:
pass
Does get the order of fields resolved before __init__
method is called ? How can I change their order ?
Update:
The above ModelForm
is used as a form in admin model which defines its own fields, so if I put all fields definition in above form, I'll get FieldError
exception about unknown field name:
class ContactAdminForm(forms.ModelForm):
...
class Meta:
model = Organization
fields = ('organization', 'oi_number', 'vat_number')
class ContactOptionsEx(ContactOptions):
form = ContactAdminForm
admin.site.register(Contact, ContactOptionsEx)
# at attempt to render the form:
# FieldError at /admin/contact/contact/3/
# Unknown field(s) (organization) specified for Organization
However the field named organization
does exist and is available in ContactAdminForm.__init__
method.
The error
does not refer to a field on your form, but to a field on the model (
Organization
).I think the problem here is that you are trying to add fields from a different Model (
OrganizationExtra
) to theModelForm
forOrganization
. There is always a one-to-one relation between aModelForm
and aModel
. If you want to edit a related instance in the admin, you can use inlines:If you want to limit the inline to one instance, use a
OneToOneField
ormax_num = 1