Необработанный запрос к postgresql в django

Пожалуйста, помогите мне с сырым запросом в postgresql:

дано models.py:

from django.db import models


class Menu(models.Model):
    name = models.CharField(max_length=255)
    menu_url = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class MenuEntry(models.Model):
    menu = models.ForeignKey("menu", null=True, blank=True,
                             on_delete=models.CASCADE)
    parent = models.ForeignKey("menuentry", null=True,
                               blank=True,
                               on_delete=models.CASCADE)
    text = models.CharField(max_length=255)

    def __str__(self):
        return self.text

Я пытаюсь получить пункт меню со связанным с ним деревом пунктов меню в другом file:

    queryset = MenuEntry.objects.raw("WITH RECURSIVE \
my_2ndmenu_items (id, parent, text) \
AS( \
SELECT * FROM menu_menuentry WHERE menu_menuentry.menu_id=(SELECT id FROM menu_menu WHERE name=%s) \
UNION \
SELECT m.* FROM menu_menuentry m \
INNER JOIN my_2ndmenu_items r ON m.parent_id = r.id \
WHERE m.parent_id IS NOT NULL \
) \
SELECT * FROM my_2ndmenu_items", ["menu_B"])

Но я получаю следующую ошибку, пытаясь получить queryset[0]:

*** ValueError: Cannot assign "'menu_B_1lvl_entry'": "MenuEntry.parent" must be a "MenuEntry" instance.

Большое спасибо за помощь!

Замена этой части вашего необработанного запроса my_2ndmenu_items (id, parent, text) \ на my_2ndmenu_items (id, parent_id, text) \ должна решить вашу проблему. Но я также рекомендую убедиться, что name в модели Menu уникален, или изменить подзапрос Menu на что-то вроде этого SELECT * FROM menu_menuentry WHERE menu_menuentry.menu_id in (SELECT id FROM menu_menu WHERE name=%s) \ в случае, если у вас есть несколько меню, соответствующих искомому названию.

Окончательный ответ:

    queryset = MenuEntry.objects.raw("WITH RECURSIVE \
my_2ndmenu_items \
AS( \
SELECT * FROM menu_menuentry WHERE menu_menuentry.menu_id=(SELECT id FROM menu_menu WHERE name=%s) \
UNION \
SELECT m.* FROM menu_menuentry m \
INNER JOIN my_2ndmenu_items r ON m.parent_id = r.id \
WHERE m.parent_id IS NOT NULL \
) \
SELECT * FROM my_2ndmenu_items", ["menu_B"])

кажется, это дает то, что я хочу спасибо всем за помощь!

Вернуться на верх