Home > Blockchain >  Django models Count and Q methods are throwing type error
Django models Count and Q methods are throwing type error

Time:03-23

I'm trying to generate dynamic query based on user input values. The normal query would be like this:

result = (
    my_model
    .objects
    .aggregate(
        Type1=Count(
            'pk',
            filter=Q(db_field=1)),
        Type2=Count(
            'pk', 
            filter=Q(db_field=2)),
        Type3=Count(
            'pk',
            filter=Q(db_field=3)),
        Type4=Count(
            'pk', 
            filter=Q(db_field=4)),
        Type5=Count(
            'pk', 
            filter=Q(db_field=5)))

This is the code I have written for my testing:

from django.db.models import (Count, Q)

field = field_values # (it's tuple and read from input)
aggregate_query = ''
if field != None:
   for j in field:
   aggregate_query  = f"{j[1]}={Count}('pk', filter={Q}(db_field={j[0]})),"

my_model.objects.aggregate(aggregate_query[:-1])

The aggregate query is generated correctly and got results when I evaluated on python console, but when I execute this code, it is throwing below error:

QuerySet.aggregate() received non-expression(s): 
Type1=<class 'django.db.models.aggregates.Count'>('pk', filter=<class 'django.db.models.query_utils.Q'>(db_field=1)),
Type2=<class 'django.db.models.aggregates.Count'>('pk', filter=<class 'django.db.models.query_utils.Q'>(db_field=2)),
Type3=<class 'django.db.models.aggregates.Count'>('pk', filter=<class 'django.db.models.query_utils.Q'>(db_field=3)),
Type4=<class 'django.db.models.aggregates.Count'>('pk', filter=<class 'django.db.models.query_utils.Q'>(db_field=4)),
Type5=<class 'django.db.models.aggregates.Count'>('pk', filter=<class 'django.db.models.query_utils.Q'>(db_field=5)).

Can someone help me on this?

CodePudding user response:

The problem is that f"{j[1]}={Count}('pk', filter={Q}(db_field={j[0]}))," is a string and you cannot query with strings.

You can construct a dict with a comprehension and then use it for the query:

from django.db.models import (Count, Q)

field = field_values
aggregate_query = {j[1]: Count('pk', filter=Q(db_field=j[0])) for j in field} if j != None else {}
my_model.objects.aggregate(**aggregate_query)
  • Related