django двойное левое соединение + django остальные рамки - PullRequest
0 голосов
/ 17 января 2019

У меня есть эти модели:

class Item(models.Model):
   name = models.CharField(max_length=100)

class Group(models.Model):
   name = models.CharField(max_length=100)

class ItemGroup(models.Model):
   item = models.ForeignKey(Item, on_delete=models.CASCADE)
   group = models.ForeignKey(Group, on_delete=models.CASCADE)

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

Я хочу запросить всех элементов, и для каждого элемента вернуть его группы в виде вложенного списка (или пустого списка, если элемент не отображается в группе).

Вот что я бы сделал с sql:

SELECT item.id, item.name, group.name
FROM items
LEFT JOIN item_group ON item.id = item_group.id
LEFT JOIN group ON group.id = item_group.group_id

(я мог бы добавить ORDER BY тоже для подкачки, но пока не обращайте внимания).

Этот запрос даст мне каждый элемент X количество групп, к которым элемент также подключен, и по крайней мере одну строку для элемента, который не отображается ни в одной группе (с группой, установленной в ноль).
Затем мне нужно будет преобразовать его во вложенный список вручную.

Вопрос:
1. Как сделать то же самое соединение с Django ORM? Это самый близкий вопрос, который я нашел: django left join
Но ответ на самом деле не левое соединение, а prefetch_related, которого я хочу избежать.
2. Если бы я создал вложенные dict таких моделей:
{item: [list of groups for the item]}. Есть ли способ передать это в django сериализаторы остальные рамки? потому что кажется, что ModelSerializer может работать только с наборами запросов.

1 Ответ

0 голосов
/ 19 января 2019

1) То, что вы хотите сделать, противоречит тому, как работает Django, и приведет к большему количеству боли, чем оно того стоит. Я бы порекомендовал сделать prefetch_related как предложено. Вы также можете изучить следующее. Вот документы на ManyToManyField .

class Item(models.Model):
    name = models.CharField(max_length=100)

class Group(models.Model):
   name = models.CharField(max_length=100)
   items = models.ManyToManyField(Group, through='ItemGroup')

class ItemGroup(models.Model):
   item = models.ForeignKey(Item, on_delete=models.CASCADE)
   group = models.ForeignKey(Group, on_delete=models.CASCADE)

2) Взгляните на ListField. Я думаю, что это должно помочь вам достичь того, что вы хотите там.

...