Muhammad Muaaz
Muhammad Muaaz

Reputation: 304

How to Convert Q Object of Django Queryset into SQL?

Suppose we have a Q expression like this:

Q(price__lt=160) | Q(publishing_date__year__gte=2016)

The SQL expression for this expression would be:

price < 160 OR YEAR(publishing_date) >= 2016

I want a package which converts these Q objects of Django into the SQL equivalent. Like:

q_obj = Q(price__lt=160) | Q(publishing_date__year__gte=2016)
sql_expression = q_obj_to_sql(q_obj) # Please, recommend if there exists such a thing

Note: Although Django provides a way to convert Querysets into SQL, but, I need to convert Q objects, and not the Querysets.

Upvotes: 0

Views: 941

Answers (1)

rgermain
rgermain

Reputation: 708

you can do this:

# is a model expample
class MyModel(models.Model):
    price = models.IntegerField()
    publishing_date = models.DateField()
    ...


from django.db.models.sql.query import Query
from django.db.models import Q
from django.db.models.sql.compiler import SQLCompiler
from django.db import connection

# your Q filter
_filter = Q(price__lt=160) | Q(publishing_date__year__gte=2016)
_query = Query(MyModel) # replace "MyModel" with your model

_compiler = SQLCompiler(_query, connection, None)
query_str, args = _filter.resolve_expression(_query).as_sql(_compiler, connection)
# query_str is a string, the result is 
#        '("my_model"."price" < %s OR "my_model"."publishing_date" >= %s)'
# args is a list, result is
#         [160, '2016-01-01']

# for replace arguments in query_str
result = query_str % tuple(args)
# WARNING , don't do this !! Security issue with sql injections.
# result :
#     '("my_model"."price" < 160 OR "my_model"."publishing_date" >= 2016-01-01)'

Upvotes: 1

Related Questions