Search code examples
pythondjangodjango-modelsdjango-1.7django-database

Django Custom lookup running different SQL query than it's displaying in str(query)


Consider the following urls.py - for brevity, I decided to put the example in one file:

from django.conf.urls import patterns, include, url

from django.http import HttpResponse
from django.db import models

def x(request):
    class A(models.Model):
        title = models.CharField(max_length=1024)
    class RightAnchored(models.Lookup):
        lookup_name = 'rightanchored'

        def as_sql(self, compiler, connection):
            lhs, lhs_params = self.process_lhs(compiler, connection)
            rhs, rhs_params = self.process_rhs(compiler, connection)
            params = lhs_params + rhs_params
            return "REVERSE(%s) LIKE REVERSE(%s)" % (lhs, rhs), params

    models.CharField.register_lookup(RightAnchored)
    q = A.objects.filter(title__rightanchored='%b')
    return HttpResponse(str(q.query))

urlpatterns = patterns('',
    url(r'^$', x),
)

For some reason, visiting http://localhost:8000 gives me: SELECT "w_a"."id", "w_a"."title" FROM "w_a" WHERE REVERSE("w_a"."title") LIKE REVERSE(%b), while running the command would result in SELECT "w_a"."id", "w_a"."title" FROM "w_a" WHERE REVERSE("w_a"."title") LIKE REVERSE('%b') (note the extra '' inside LIKE REVERSE). This means that the displayed query is different than one that is being run. How can I make my Lookup behave properly when str(q.query) is called?


Solution

  • str(qs.query) doesn't do correct quoting on all backends. This is because the quoting is handled by the database driver, and some drivers do not give access to the quoted query string.

    So, in short, everything is working correctly.