Django ORM "filter" method produces SQL query without quotes

Question:

I am building an app with Django relying on several PosgreSQL databases which I do not manage, let’s call them database A and database B. For each database, I’ve used python manage.py inspectdb to build my models.py files.

I am trying to use Django ORM to perform the following query (significantly simplified here), to_date being a datetime.datetime object:

sample = my_model_in_B.objects
    .filter(a_column=instance_of_a_model_in_A.name)
        .exclude(another_column='Useless things')
            .filter(a_column_with_dates__lte=to_date)

My issue is that it produces the following SQL query:

SELECT "myschema"."mytable"."a_column", "myschema"."mytable"."another_column" from "myschema"."mytable"
WHERE "myschema"."mytable"."a_column" = Here is the name of instance_of_a_model_in_A
AND "myschema"."mytable"."a_column_with_dates" <= 2020-02-03
AND NOT ("myschema"."mytable"."another_column" = Useless things
AND "myschema"."mytable"."another_column" IS NOT NULL))

In other terms, my issue is that the Django ORM does not automatically add quotes where I need them. I don’t understand what I did wrong. I don’t know if that matters but note that:

  • I use Django 2.2. and my database B is POSTGRESQL 8 only,
  • All the columns that I use correspond to CharField in my models, except a_column_with_dates which corresponds to a DateField.
Asked By: scūriolus

||

Answers:

Actually, my initial question was wrongly worded and misleading. I was assuming that QuerySet.query (that I used to get the above SQL code) was supposed to return the valid SQL query behind Django ORM, but it isn’t. It just aims at providing a basic representation of the query, nonetheless, from a comment made on the official Django project website:

Django never actually interpolates the parameters: it sends the query
and the parameters separately to the database adapter, which performs
the appropriate operations.

Indeed, from the official documentation:

The query parameter to QuerySet exists so that specialized query subclasses can reconstruct internal query state. The value of the parameter is an opaque representation of that query state and is not part of a public API.

Answered By: scūriolus