Django - Как получить все связанные объекты в модели отношений пользователя с одним набором запросов - PullRequest
1 голос
/ 07 мая 2019

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

Пример: я получил модель 2 отношений с моделью пользователя, я могу получитьобъекты с этим кодом ниже

User.objects.get(id=1).profile
User.objects.get(id=1).groups

Но как мне получить все объекты пользователя только с одним набором запросов ...

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Используйте select_related и prefetch_related, как описано здесь :

user = User.objects.select_related('profile').prefetch_related('groups').get(id=1)
user.profile  # does not query the database again
user.groups  # does not query the database again

Обратите внимание, что, поскольку user <-> groups является отношением m2m, в любом случае это попадет в базу данных дважды. Если вы выбираете только одного конкретного пользователя, добавление prefetch_related на самом деле не имеет значения. Это имеет значение, если вы просматриваете список пользователей, так как для выборки всех связанных с m2m групп требуется только один запрос вместо одного запроса для каждого пользователя:

users = User.objects.select_related('profile').prefetch_related('groups')\
     .filter(is_staff=True)
for user in users:  # 2 queries
    print(user.profile)
    for group in user.groups:  # no database query
        print(group.name)
0 голосов
/ 07 мая 2019

Вы можете получить доступ к данным ManyToMany, данных внешнего поля в наборе запросов с нижним подчеркиванием в формате ниже.

columnname.referred.table__reference_column


class DigitalApplicationsAndPlatform(models.Model):    
    digital_area = models.ForeignKey(MasterDigitalProductsAreas, on_delete=models.CASCADE)    
    keywords = models.ManyToManyField("MasterKeyword", blank=True, related_name="digital_keyword")

Набор запросов:

m = models.DigitalApplicationsAndPlatform.objects.filter(id=1).values('digital_product', 'digital_area__digital_area', 'keywords__keyword')

Над набором запросовбудет иметь несколько значений digital_product, digital_area__digital_area, поскольку поле ключевых слов имеет отношение ManyToMany.

Результат:

<QuerySet [{'digital_product': '10,000ft Insights', 'digital_area__digital_area': 'Productivity & Collaboration', 'keywords__keyword': '_10000ft Insights_'}, {'digital_product': '10,000ft Insights', 'digital_area__digital_area': 'Productivity & Collaboration', 'keywords__keyword': '_10K Insights_'}, {'digital_product': '10,000ft Insights', 'digital_area__digital_area': 'Productivity & Collaboration', 'keywords__keyword': '_10,000ft Insights_'}, {'digital_product': '10,000ft Insights', 'digital_area__digital_area': 'Productivity & Collaboration', 'keywords__keyword': "_10K' Insights_"}]>

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

m =    models.DigitalApplicationsAndPlatform.objects.filter(id=1).select_related('digital_area').prefetch_related('keywords').values('digital_product',    'digital_area__digital_area', 'keywords__keyword')

Вы используете нижеприведенные подсказки, чтобы справиться с вышеуказанным набором запросов.

  • select_related - для внешнего ключа и поля OneToOne.
  • prefetch_related - для ManyToMany и обратного просмотра

Ниже официальный документ даст представление о доступе к связанным данным.

https://docs.djangoproject.com/en/2.2/topics/db/queries/#lookups-that-span-relationships

...