Django 1.11 Annotate subquery with .exclude or ~Q() does not work

116 views Asked by At

Is it not possible to exclude inside a queryset? I always receive this error:

ValueError: This queryset contains a reference to an outer query and may only be used in a subquery.

The part of the code I am wondering why is it not working:

 def get_queryset(self):
    return self.queryset.annotate(
        foo_count=Subquery(
            Foo.objects.exclude(code__hash=OuterRef('hash'))
            .values('code')
            .annotate(cnt=Count('pk'))
            .values('cnt'),
            output_field=IntegerField()
        ),
    )
1

There are 1 answers

0
Forged On BEST ANSWER

Just found out that it is not possible to .exclude or negate ~Q() with OuterRef() for that Django version.

Found the similiar issue here: https://code.djangoproject.com/ticket/30739

The workaround is to get RAW SQL Query from self.queryset.annotate and reformat it in the way you need.

Here is an example of a solution that worked for me:

return self.queryset.annotate(
    device_count_behind = RawSQL('''SELECT (your query)...''', (), IntegerField()),
)