Ошибка поля для django Prefetch() при разрешении отношений ManyToMany
Вот мои модели:
class Element(models.Model):
name = models.CharField(max_length=255)
creator = models.ForeignKey(User, related_name='element_creator', on_delete=CASCADE)
element_type = models.ForeignKey('ElementType', on_delete=CASCADE)
create_date = models.DateTimeField(auto_now_add=True)
modif_date = models.DateTimeField()
description = models.TextField(blank=True, null=True)
class Meta:
managed = True
class ElementWorkingSet(models.Model):
name = models.CharField(max_length=255)
owner = models.ForeignKey(User, on_delete=CASCADE)
create_date = models.DateTimeField(auto_now_add=True)
modif_date = models.DateTimeField(auto_now=True)
project = models.ForeignKey(Project, on_delete=CASCADE)
active = models.BooleanField(default=True)
elements = models.ManyToManyField(Element,
through='ElementSet2Element',
through_fields=('element_working_set', 'elements'),
)
class Meta:
managed = True
class ElementSet2Element(models.Model):
element_working_set = models.ForeignKey('ElementWorkingSet',
on_delete=CASCADE)
elements = models.ForeignKey(Element, on_delete=CASCADE)
active = models.IntegerField()
element_owner = models.ForeignKey(User, on_delete=CASCADE)
approver = models.ForeignKey(User, null=True, related_name='+', on_delete=CASCADE)
class Meta:
managed = True
Я извлекаю список ElementWorkingSet и хочу отобразить дочерние элементы с element_owner
а также approver
от ElementSet2Element
Таблица.
Сначала я выполнял много отношений без использования prefetch_related, но это оказалось крайне неэффективным. До того времени, когда мне нужно было element_owner
а также approver
Время отклика было приличным. Но извлечение этих полей сделало это очень медленно.
Я пытаюсь изменить свой запрос, чтобы выполнить более эффективный запрос, используя следующий запрос:
query = ElementWorkingSet.objects.filter(
project__id=project_id, active=True).select_related(
'owner'
).prefetch_related(
Prefetch(
'elements',
queryset=ElementSet2Element.objects.select_related(
'elements',
'approver',
'element_owner'
),
),
)
Проблема в том, что Django возвращает следующую ошибку:
Cannot resolve keyword 'elementworkingset' into field. Choices are: active, approver, approver_id, id, element_owner, element_owner_id, element_working_set, element_working_set_id, elements, elements_id
Я не пользуюсь elementworkingset
в качестве переменной в любом месте. На самом деле это не происходит нигде в моем проекте. После отладки я заметил, что это происходит от ElementWorkingSet
название модели.
Я понятия не имею, почему это происходит, и что я могу сделать, чтобы это исправить. Я использую Django 1.9 и Python 3.6 с базой данных MySQL.
1 ответ
Проблема в том, что вы заявили
elements = models.ManyToManyField(
Element,
through='ElementSet2Element',
through_fields=('element_working_set', 'elements'))`
Это совершенно правильно, однако, когда вы проходите 'elements'
в Prefetch
, он определяет, что это отношение к модели Element, а не ElementSet2Element, как вы ожидали (да, это делает довольно умные вещи). Итак, обратное имя поля для элемента elementworkingset
потому что вы не объявили другие через related_query_name
или же related_name
в вашем models.ManyToManyField
( документы). Тогда вы проходите ElementSet2Element
queryset и django пытается найти elementworkingset
в этом. Так как у вас нет такого поля в ElementSet2Element
, это не удается.
Итак, вместо 'elements'
ты должен пройти 'elementset2element_set'
в Prefetch