Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter Django's CommaSeparatedIntegerField

Assume a model

class Foo(models.Model):
    bar = models.CommaSeparatedIntegerField('Filter Me!')

The content of the bar could look like, e.g., 12,35,67,142.

I want to query all Foos, that have a 42 in bar:

all_42_foos = Foo.objects.filter(bar__contains="42")

which doesn't give the correct result, since CommaSeparatedIntegerField inherits from CharField and the filter evaluation uses the string content of the field (matching the above example with 142, too).

How can I hav a filter, that does a .split(",") on the bar field before it checks for the 42? I really don't want bar to become a ManyToMany, since it'd be a terrible overhead.

like image 946
Boldewyn Avatar asked Nov 15 '10 11:11

Boldewyn


1 Answers

What about something like:

from django.db.models import Q

all_42_foos = Foo.objects.filter( Q(bar__startswith='42,') | Q(bar__endswith=',42') | Q(bar__contains=',42,') | Q(bar__exact='42') )

While it's a bit of a verbose query, I think something along those lines will be the only way to get what you're looking for. It's probably worth turning that into a separate function along the lines of

def all_x_foos(x):
    return Foo.objects.filter( Q(bar__startswith=x+',') | Q(bar__endswith=','+x) | Q(bar__contains=',{0},'.format(x)) | Q(bar__exact=x) )

Out of curiosity, have you checked the actual performance of your app w/ both the many-to-many way, and the pseudo-many-to-many method you're describing?

like image 173
desfido Avatar answered Nov 02 '22 21:11

desfido