﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
34791	Prefetch's queryset attribute is ignored when the same nested relation is used multiple times.	Maxime Toussaint	Maxime Toussaint	"Note: Edited the description following the discussion

There seems to be an issue when using a Prefetch object to fetch something that has already been fetched. The issue only seems to happen when there is depth in the prefetch. Here is an example I made this morning that fails:
{{{
        pizzas = Pizza.objects.all().prefetch_related(
            ""toppings__origin"",
            Prefetch(
                ""toppings__origin"",
                queryset=Country.objects.filter(label=""China""),
                to_attr=""china"",
            ),
        )

        china = pizzas[0].toppings.all()[0].china
}}}
Here, when trying to get china, I would assume it to either be a Country object or None. However, I get the message: AttributeError: 'Topping' object has no attribute 'china'

Here are the models I set up for my test:
{{{
class Country(models.Model):
    label = models.CharField(max_length=50)


class Pizza(models.Model):
    label = models.CharField(max_length=50)


class Topping(models.Model):
    pizza = models.ForeignKey(Pizza, on_delete=models.CASCADE, related_name=""toppings"")
    label = models.CharField(max_length=50)
    origin = models.ForeignKey(
        Country, on_delete=models.CASCADE, related_name=""toppings""
    )
}}}
And here are the queries made when calling the queryset:
{{{
1. SELECT ""tests_pizza"".""id"", ""tests_pizza"".""label"", ""tests_pizza"".""provenance_id"" FROM ""tests_pizza""
2. SELECT ""tests_topping"".""id"", ""tests_topping"".""pizza_id"", ""tests_topping"".""label"", ""tests_topping"".""origin_id"" FROM ""tests_topping"" WHERE ""tests_topping"".""pizza_id"" IN (1, 2)
3. SELECT ""tests_country"".""id"", ""tests_country"".""label"", ""tests_country"".""continent_id"" FROM ""tests_country"" WHERE ""tests_country"".""id"" IN (2, 3, 4)
}}}
Note that the filter by label='china' has completely disappeared.

Now, if I switch the prefetches around like so:
{{{
        pizzas = Pizza.objects.all().prefetch_related(
            Prefetch(
                ""toppings__origin"",
                queryset=Country.objects.filter(label=""China""),
                to_attr=""china"",
            ),
            ""toppings__origin"",
        )
}}}
Fetching china now works, and here are the queries being made:
{{{
1. SELECT ""tests_pizza"".""id"", ""tests_pizza"".""label"", ""tests_pizza"".""provenance_id"" FROM ""tests_pizza""
2. SELECT ""tests_topping"".""id"", ""tests_topping"".""pizza_id"", ""tests_topping"".""label"", ""tests_topping"".""origin_id"" FROM ""tests_topping"" WHERE ""tests_topping"".""pizza_id"" IN (1, 2)
3. SELECT ""tests_country"".""id"", ""tests_country"".""label"", ""tests_country"".""continent_id"" FROM ""tests_country"" WHERE (""tests_country"".""label"" = 'China' AND ""tests_country"".""id"" IN (2, 3, 4))
4. SELECT ""tests_country"".""id"", ""tests_country"".""label"", ""tests_country"".""continent_id"" FROM ""tests_country"" WHERE ""tests_country"".""id"" IN (2, 3, 4)
}}}
This time, both calls to Country were made.

I did follow the code a bit yesterday, and I believe it comes from the fact that the ForeignKey field defines the cache name as being simply the name of the field. I am not certain though, and it would likely require someone with more knowledge than me to look into it."	Bug	closed	Database layer (models, ORM)	4.2	Normal	fixed	prefetch, prefetch_related		Ready for checkin	1	0	0	0	0	0
