Предварительная выборка дополнительных полей в таблице 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
)