2

I'm trying to concatenate many querysets together. I tried out the marked answer from this question a while back, but that didn't work in my case. I needed to return a queryset not a list. So I used the |, from the second answer. This worked fine at the time, but now that I'm trying to use it again for something else I get the following error:

Expression tree is too large (maximum depth 1000)

I originally thought that | would concat the querysets, but after reading the docs it appears that it concats the actual query. And that this specific problem occurs if the query becomes too long/complex.

This is what I'm trying to do:

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])

Since the functions query returns roughly 1200 results, and each function has about 5 properties, I can understand the query becoming too long/complex.

How can I prevent the query from becoming too complex? Or how can I execute multiple queries and concat them afterwards, while keeping the end result a queryset?

Community
  • 1
  • 1
Snackoverflow
  • 736
  • 9
  • 31

1 Answers1

2

I think you want to obtain all the Property objects that have as Function a certain project.

We can query this with:

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

This thus is a queryset that contains all property objects for which the function (I assume this is a ForeignKey) has as project (probably again a ForeignKey is the given project). This will result in a single query as well, but you will avoid constructing gigantic unions.

Alternatively, you can do it in two steps, but this would actually make it slower:

# probably less efficient
function_ids = (Function.objects.filter(project=project)
                                .values_list('pk', flat=True))
properties = Properties.object(function_id__in=function_ids)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555