#23805: query `first` method clears cached queryset for prefetch_related ----------------------------------------------+------------------------- Reporter: alecklandgraf | Owner: nobody Type: Uncategorized | Status: new Component: Database layer (models, ORM) | Version: master Severity: Normal | Keywords: first query Triage Stage: Unreviewed | Has patch: 0 Easy pickings: 0 | UI/UX: 0 ----------------------------------------------+------------------------- When a cached queryset is iterated through with `prefetch_related`, if `.first()` is called during the iteration, a new DB query is fired off. This is potentially due to the LIMIT 1 `[:1]` or the `order_by` added to the queryset with the `first` method.
https://github.com/django/django/blob/master/django/db/models/query.py#L518 ex. {{{ from django.db import connection connection.queries = [] pizzas = Pizza.objects.all().prefetch_related('toppings') print len(connection.queries) # 2 for pizza in pizzas: first_topping = pizza.toppings.first() print len(connection.queries) # 2 + number of pizzas }}} This fixes in my code at least: {{{ from django.db import connection connection.queries = [] pizzas = Pizza.objects.all().prefetch_related('toppings') print len(connection.queries) # 2 for pizza in pizzas: try: first_topping = pizza.toppings.all()[0] except IndexError: first_topping = None print len(connection.queries) # 2 }}} -- Ticket URL: <https://code.djangoproject.com/ticket/23805> 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 django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/056.ad1f70f04eaac67d22f7f3ed32d487b4%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.