Django, используя «|»: дерево выражений слишком большое (максимальная глубина 1000) - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь объединить множество наборов запросов вместе. Некоторое время назад я попробовал отмеченный ответ из этого вопроса, но в моем случае это не сработало. Мне нужно было вернуть queryset не список. Поэтому я использовал |, из второго ответа. В то время это работало нормально, но теперь, когда я пытаюсь использовать его снова для чего-то другого, я получаю следующую ошибку:

Expression tree is too large (maximum depth 1000)

Первоначально я думал, что | будет согласовывать наборы запросов, но после прочтения документов выясняется, что он соответствует фактическому запросу. И эта конкретная проблема возникает, если запрос становится слишком длинным / сложным.

Вот что я пытаюсь сделать:

def properties(self, request, pk=None):
    project = self.get_object()
    if project is None:
        return Response({'detail': 'Missing project id'}, status=404)

    functions = Function.objects.filter(project=project)
    properties = Property.objects.none()
    for function in functions:
        properties = properties | function.property_set.all()
    return Response([PropertySerializer(x).data for x in properties])

Поскольку запрос functions возвращает примерно 1200 результатов, а каждый function имеет около 5 свойств, я могу понять, что запрос становится слишком длинным / сложным.

Как я могу предотвратить слишком сложный запрос? Или как я могу выполнить несколько запросов и объединить их впоследствии, сохранив конечный результат как набор запросов?

1 Ответ

0 голосов
/ 17 мая 2018

Я думаю, что вы хотите получить все Property объекты, которые имеют Function определенный проект.

Мы можем запросить это с помощью:

properties = Property.objects.filter(function__project=project)

Таким образом, этонабор запросов, который содержит все объекты свойств, для которых function (я предполагаю, что это ForeignKey) имеет значение project (вероятно, снова ForeignKey - данное project).Это также приведет к одному запросу, но вы избежите создания гигантских союзов.

В качестве альтернативы, вы можете сделать это в два шага, но на самом деле это замедлит процесс:

# probably less efficient
function_ids = (Function.objects.filter(project=project)
                                .values_list('pk', flat=True))
properties = Properties.object(function_id__in=function_ids)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...