Custom lookup field for text comparison in Django 1.6

160 views
Skip to first unread message

Jorge Arévalo

unread,
Mar 4, 2015, 2:15:32 PM3/4/15
to django...@googlegroups.com
Hello,

I'm trying to emulate a non-spaces-all-lower text comparison filter in Django 1.6.x. In other words, I want the equivalent to this query

select * from myapp_mymodel where replace(lower(str), " ", "") = '<user_entry>'

Being my model something like this

from django.db import models

class MyModel(models.Model):
    num = models.IntegerField()
    str = models.CharField(max_length=16)

In my mind, this can be implemented with a custom lookup like this:

MyModel.objects.filter(str__customcomparison='spaces and UPPERCASE will not be taken into account')

I know Django 1.7 allows custom lookups creation, but can't make Django 1.6 work like this. I've tried implementing a custom QuerySet and a custom Manager for MyModel. In the custom QuerySet, I override the method _filter_or_exclude. 

Am I in the right path? Any suggestion?

Many thanks in advance

Simon Charette

unread,
Mar 4, 2015, 2:48:50 PM3/4/15
to django...@googlegroups.com
Hi Jorgue,

As you already know there's no officially supported API to create custom lookups in Django < 1.7

However it's possible to get something working by monkey patching WhereNode.make_atom.

Here's an example GIST that expose a decent API to add custom lookups.

From importing the lookups module you should be able to register your custom lookup this way:

def db_prepare_customcomparison(value, connection, prepared):
    return [value.replace(' ', '').lower()]

lookups.register(
    'customcomparison',
    'replace(lower(%s), " ", "") = %%s',
    db_prepare=db_prepare_customcomparison,
)

Note that you should use this code at your own risk since it's messing with Django's internal and I would strongly advise you to move to 1.7 instead since 1.6 is approaching end of support.

Simon
Reply all
Reply to author
Forward
0 new messages