Opened 8 years ago

Last modified 8 years ago

#26800 closed Uncategorized

Model FormSet & Prefetch ordered — at Version 1

Reported by: Adrien mille Owned by: nobody
Component: Uncategorized Version: 1.9
Severity: Normal Keywords: formset preferch order_by ordered model
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Adrien mille)

I happened to meet some unexpected behavior while mixing together the Model FormSet with a Queryset on which I had prefetch.

My setup is the following one ;

prefetch = Prefetch('childs', Child.objects.order_by('order')),
queryset = Parent.objects.prefetch_related(prefetch)
parent = queryset.get(pk=42)
formset = ChildFormSet(queryset=parent.childs.all())

Everything works without warning or error, however the formset does not respect the queryset I provide. I tried to understand a bit more about the reasons behind it and I finally see the folloxing lines in BaseModelFormSet.get_queryset() ;

# If the queryset isn't already ordered we need to add an
# artificial ordering here to make sure that all formsets
# constructed from this queryset have the same form order.
if not qs.ordered:
     qs = qs.order_by(self.model._meta.pk.name)

So I went to read my queryset object and I saw that the property ordered is to False while the results are correctly ordered (the property _prefetch_done is True on my queryset object). So my thinking is that the queryset resulting of parent.object.all() is my prefetch (as expected) but not ordered as my FormSet expects. So it does order it by the primary key for the model and breaks my prefetch.

I checked twice on the documentation and source code but I didn't see any warning about putting together prefetch & formset, especially on ordered queryset.

Change History (1)

comment:1 by Adrien mille, 8 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top