Opened 3 years ago
Closed 3 years ago
#33950 closed Bug (duplicate)
ModelChoiceField and chained prefetch_related(): queries made twice
| 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 (last modified by )
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.fields["documents_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("visits__documents")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if "visit_forms" not in context:
context["visit_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.
Then the queries are made twice, erasing the prefetch_related() effect.
Many thanks!
Change History (3)
comment:1 by , 3 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 3 years ago
| Description: | modified (diff) |
|---|
comment:3 by , 3 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
Duplicate of #22841.