Opened 2 years ago
Last modified 2 years ago
#33950 closed Bug
ModelChoiceField and chained prefetch_related(): queries made twice — at Initial Version
Reported by: | Vincent Lefoulon | Owned by: | nobody |
---|---|---|---|
Component: | Uncategorized | Version: | 3.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hi!
I have these three models:
`
class Place(models.Model):
name = models.CharField(max_length=255)
class Visit(models.Model):
date = models.DateField()
place = models.ForeignKey(Place, on_delete=models.CASCADE, related_name="visits")
class VisitDocument(models.Model):
visit = models.ForeignKey(Visit, on_delete=models.CASCADE, related_name="documents")
file = models.FileField()
`
A form to edit a visit:
`
class VisitForm(forms.ModelForm):
class Meta:
model = Visit
exclude = ("place",)
def init(self, *args, kwargs):
super().init(*args, kwargs)
self.fieldsdocuments_to_delete = forms.ModelMultipleChoiceField(
queryset=self.instance.documents.all(),
required=False,
)
`
And a generic view for the places:
`
class PlaceView(DetailView):
queryset = Place.objects.prefetch_related("visitsdocuments")
def get_context_data(self, kwargs):
context = super().get_context_data(kwargs)
if "visit_form" not in context:
contextvisit_forms = [
VisitForm(instance=visit)
for visit in self.object.visits.all()
]
def post(self, request, *args, kwargs):
Handle the form
`
Despite the prefetch_related("visits__documents")
call in my view, ModelMultipleChoiceField()
doesn't detect that the documents of the visit (i.e. the form instance) are already fetched because visit.documents.all()._prefetch_related_lookups
is null: https://github.com/django/django/blob/stable/3.2.x/django/forms/models.py#L1167
So is in the view: self.object.visits.all()._prefetch_related_lookups
is null as well.
Many thanks!