Делает ли Django дополнительный запрос на доступ к предварительно выбранному полю M2M через «values ​​()» или «values_list ()»? - PullRequest
0 голосов
/ 23 мая 2019

models.py :

class DemoA(models.Model):
    M = < M2M-Field to DemoB>

class DemoB(models.Model):
    title = < CharField >

Queryset с предварительной выборкой:

qs = DemoA.objects.all().prefetch_related('M')

prefetch_related хорошо работает, когдаиспользуется с .all(), как указано в документах .

Например:

# This is the expected use case and will not make any additional query
for row in qs:
    print(row.M.all())

1) Что теперь, если я попытаюсь получить к нему доступ, используя методы .values() или .values_list()?Будут ли выполнены дополнительные запросы?

Например:

print(qs.values('M'))

# OR

print(qs.values_list('M'))

2) Дополнительно:

Что если я получу доступ ксвойство M аналогичным образом?Будет ли он делать какой-либо дополнительный запрос?

Например:

print(qs.values('M__title'))

Если он делает запрос (ы) в обоих случаях, что является идеальнымспособ сделать то же самое?Хорошо ли перебирать все и извлекать их свойства?

1 Ответ

0 голосов
/ 24 мая 2019

Да.Это сделает дополнительный запрос.

Причина:

«Предварительно выбранный» набор запросов относится к классу модели DemoB.При доступе через row.M.all() используемый набор запросов относится к классу модели DemoB, и запрос остается тем же.Принимая во внимание, что в случае print(qs.values('M')) набор запросов используется для класса модели DemoA, и, следовательно, встроенный запрос отличается.

И в соответствии с документами:

Помните, что, как всегда с QuerySets, любые последующие цепочечные методы, которые подразумевают другой запрос к базе данных, будут игнорировать ранее кэшированные результаты, и извлекать данные, используясвежий запрос к базе данных.

...