#33950: ModelChoiceField and chained prefetch_related(): queries made twice
--------------------------------------------+------------------------
               Reporter:  Vincent Lefoulon  |          Owner:  nobody
                   Type:  Bug               |         Status:  new
              Component:  Uncategorized     |        Version:  3.2
               Severity:  Normal            |       Keywords:
           Triage Stage:  Unreviewed        |      Has patch:  0
    Needs documentation:  0                 |    Needs tests:  0
Patch needs improvement:  0                 |  Easy pickings:  0
                  UI/UX:  0                 |
--------------------------------------------+------------------------
 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_form" 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.

 Many thanks!

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33950>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070182ca2b47a6-27223098-2d61-4745-b270-75c75c6385d1-000000%40eu-central-1.amazonses.com.

Reply via email to