Предварительная выборка дополнительных полей в таблице ManyToMany

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

Рассмотрим пример из документации Django :

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

Я хотел бы сделать следующее: из каждой сущности класса Group получить все сущности класса Person и получить все поля invite_reason или date_joined.

Для извлечения персон, он идет быстро с атрибутом QuerySet.prefetch_related, который предотвращает поток запросов к базе данных, вызванный обращением к связанным объектам.

groups = (Group.objects.prefetch_related('members')

Однако я не нашел решения для получения в постоянном времени доступа дополнительных полей invite_reason и date_joined.

Я пробовал использовать префетч membership_set или связанное имя в моей переменной groups, но мой код не работает быстрее.

# NOT WORKING
groups = (Group.objects.prefetch_related('members', 'membership_set')

Я также пробовал использовать Prefetch объект с queryset параметром с помощью select_related, но это не сработало. Все, что я пытался загрузить все данные Membership в groups при инициализации, потерпело неудачу, и в итоге у меня очень долгое время выполнения для извлечения дополнительных полей из таблицы.

for group in groups:
    invite_reason_list = group.membership_set.values_list('invite_reason', flat=True)
    date_joined_list = group.membership_set.values_list('date_joined', flat=True)

Есть ли какое-нибудь решение, чтобы остановить поток запросов к базе данных, вызванный обращением к связанным объектам?

Заранее спасибо

Когда вы не пишете related_name.all() при предварительной выборке, это не работает так, как ожидалось. вы можете получить данные следующим образом:

prefetch_membership_set = models.Prefetch('membership_set',
                                              Membership.objects.only(
                                                  'date_joined', 'invite_reason'))

groups = Group.objects.prefetch_related(prefetch_membership_set)
for group in groups:
    invite_reason_list = []
    date_joined_list = []
    for membership in group.membership_set.all():
        invite_reason_list.append(
            membership.invite_reason
        )
        date_joined_list.append(
            membership.date_joined
        )
Вернуться на верх