In Django, I'm using an inlineformset with can_order = True
, on a model that has order_with_respect_to
set. I've set up drag and drop on the front end, which results in Django's autogenerated ORDER form fields (which I've hidden) changing to reflect the new order. I've verified I'm POSTing the new order correctly to the server, but Django seems to ignore it, and saves the models in the original order. The automatically-created _order
fields in the database never change.
How can I get Django to save the models using order specified in the formset? Do I need to do anything special other than calling save()
on the formset?
Django formset allows you to edit a collection of the same forms on the same page. It basically allows you to bulk edit a collection of objects at the same time.
Django model formsets provide a way to edit or create multiple model instances within a single form. Model Formsets are created by a factory method. The default factory method is modelformset_factory(). It wraps formset factory to model forms. We can also create inlineformset_factory() to edit related objects.
Evan Borgstrom proposed solution does not work together with can_delete=True
.
Here is my solution that also works with can_delete=True
:
for instance in formset.save(commit=False):
# ... do something with m2m relationships ...
for form in formset.ordered_forms:
form.instance.order = form.cleaned_data['ORDER']
form.instance.save()
I had the same problem and after digging through the Django source figured that it's something you need to do on your own.
My original implementation looked something like this:
services = service_formset.save(commit=False)
for service in services:
# ... do something with m2m relationships ...
service.save()
However, as you've found this doesn't set the ORDER. So instead my implementation now looks like:
for form in service_formset:
service = form.save(commit=False)
# ... do something with m2m relationships ...
service.order_order = form.cleaned_data['ORDER']
service.save()
In my example above 'order_order' is the field I'm using to track order on my models.
Also remember that you need to specify the 'ordering' attribute of your model's Meta class to ensure that when you generate the formset again the elements are in the correct order.
class Service(models.Model):
# ...
order_order = models.IntegerField(default=0)
class Meta:
ordering = ['order_order',]
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