У меня есть рекурсивная модель Case (модель имеет собственную ссылку, называемую родительской), и я хочу аннотировать запросы в наборе запросов с корневым родителем.
Итак, если у меня есть корень A с дочерним B, у которого есть дочерний C, я хочу, чтобы набор запросов, содержащий все три, имел ссылку на A. Я создал sql, который выполнил это для отдельного Case, но яне могу понять, как аннотировать набор запросов с ним.Я экспериментирую с подклассом django.db.models.Func, но не могу заставить его работать.
Модель:
class Case(CoreModel):
... fields ...
parent = ForeignKey(
'Case',
verbose_name=ugettext_lazy("Parent case"),
null=True,
blank=True,
on_delete=models.SET_NULL,
)
SQL-запрос, который работает:
query = '''
WITH RECURSIVE Ancestors AS (
SELECT id, parent_id FROM core_case m where id = %(expressions)s
UNION ALL
SELECT m.id, m.parent_id
FROM Ancestors
JOIN core_case m on m.id=Ancestors.parent_id
)
SELECT id, parent_id FROM Ancestors WHERE parent_id IS NULL
'''
текущая попытка подкласса Func:
class RootCase(Func):
template = query
def __init__(self, *expressions):
super(RootCase, self).__init__(*expressions, output_field = IntegerField())
При тестировании
cases = (
Case
.objects
.filter(customer__company=514)
.annotate(root=RootCase(7401))
)
Неудача:
django.db.utils.ProgrammingError: syntax error at or near "WITH"
Ход выполнения: Iтеперь я могу аннотировать набор запросов с помощью запроса, но не могу получить ссылку для каждого дела, переданного запросу
cases = (
Case
.objects
.filter(customer__company=514)
.annotate(root=RawSQL(query, (7401,))
)
)
Это работает, но всегда помечается корневым родителем 7401
cases = (
Case
.objects
.filter(customer__company=514)
.annotate(root=RawSQL(query, (OuterRef('pk'),))
)
)
Это не с:
django.db.utils.ProgrammingError: can't adapt type 'OuterRef'