Changing the display order of forms in a formset
django, python
Solution
To complete the answers. There are two ways how you can control the order of forms in the formset: formsets respect order of given queryset (this is shown in other replies). Another way (if you want to have the order of the forms fully under control) is to define custom formset class and override `__iter__` and `__getitem__` methods:
from django.forms import BaseModelFormSet
class MyModelBaseFormset(BaseModelFormSet):
def __iter__(self):
"""Yields the forms in the order they should be rendered"""
return ...
def __getitem__(self, index):
"""Returns the form at the given index, based on the rendering order"""
return ...
MyModelFormset = modelformset_factory(model=MyModel, formset=MyModelBaseFormset, queryset=...)
This approach is described in the Django documentation:
Iterating over the formset will render the forms in the order they were created. You can change this order by providing an alternate implementation for the `__iter__()` method.
Formsets can also be indexed into, which returns the corresponding form. If you override `__iter__`, you will need to also override `__getitem__` to have matching behavior.
https://docs.djangoproject.com/en/dev/topics/forms/formsets/#django.forms.formsets.BaseFormSet
The example of implementing these methods is for example in this SO thread: modelformset __iter__ overloading problem.
Problem
I am displaying a modelformset and I would like the forms to be ordered by the contents of one of its fields. So I want to use the equivalent of `SomeModel.objects.filter(whatever).order_by('somefield')` for a (model)formset in a template. How can I do this? Note that `can_order` does not do what I want (it must be automatic, not user specified). I have also tried other things, like the dictsort filter, but that produces unpredictable output (i.e. not ordered by the specified field). I even tried `{% regroup formset by somefield as sorted_formset %}`, but the resulting `sorted_formset` cannot be used (iterated) as a normal formset.