Form Inheritance. Order is Reversed.

124 views
Skip to first unread message

Justin J

unread,
Jan 9, 2017, 12:19:34 PM1/9/17
to Django users
I have a form which is sublassing 3 forms, and has no new fields.

class D(A, B, C):
pass

form class B is subclassing 2 forms.

class B(B1, B2):
pass


In the template I am looping through the form.

{% for d in forms.myforms %}
{% for field in d.form.visible_fields %}

{% endfor %}
{% endfor %}


This was working as expected until recently. Form classes A, B, C are displayed in reverse order now, and B1, B2 are also reversed. However, fields within B2 are still in the order declared.

The only thing I can think of that changed recently was an upgrade from Django 1.5 to 1.8. I have no clue if it is related.

Anyone experience this before?

Thanks for any suggestions.



Matthew Pava

unread,
Jan 10, 2017, 9:59:34 AM1/10/17
to django...@googlegroups.com

Hi Justin,

 

Something that caught my eye is {% for d in forms.myforms %}.  If you have one form, D, then I don’t think you should need to loop through the other forms.

 

After saying that, it does look like there was a change in field order in Django 1.7.

See https://github.com/pennersr/django-allauth/issues/356#issuecomment-24758824.

 

See also this Stack Overflow post for a similar discussion:

http://stackoverflow.com/questions/913589/django-forms-inheritance-and-order-of-form-fields

 

If you upgrade Django 1.9, you can utilize the field_order attribute on the Form class to specify the order of the fields:

https://docs.djangoproject.com/en/1.10/ref/forms/api/#notes-on-field-ordering

 

And you may want to consider using Django-crispy-forms for form rendering:

https://github.com/django-crispy-forms/django-crispy-forms

 

Thank you,

Matthew

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/8caa622b-5cf2-4869-aa0f-a7aa68a3b50f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Justin J

unread,
Jan 10, 2017, 11:34:22 AM1/10/17
to Django users
Thanks Mathew,

I do have multiple forms, and that is why the nested loop.

I'm going to try to upgrade to the latest 1.10 and see if it solves the problem. If anything I will be able to use the field_order attribute.

I reverted to a commit before I upgraded from 1.5 to 1.8 and the problem was not present, so I suspect the upgrade changed some related behavior. Maybe it was that change in ver. 1.7 as you suggested.

Justin J

unread,
Jan 11, 2017, 3:55:39 PM1/11/17
to Django users
For anyone interested,

In django/django/forms/forms.py  ln 45:

# Walk through the MRO.
declared_fields = OrderedDict()
for base in reversed(new_class.__mro__):
# Collect fields from base class.
if hasattr(base, 'declared_fields'):
declared_fields.update(base.declared_fields)


"reverse(new_class.__mro__)" is causing order of inherited forms to be reversed. 
DeclarativeFieldsMetaclass was reworked for version 1.7 and I don't know what the intended behavior is so I am not opening a ticket.

I tested with two unrelated Django applications and I found the same results in both.

Reply all
Reply to author
Forward
0 new messages