I've been trying to filter a queryset on a simple model but with no luck so far.
Here is my model:
class Country(models.Model):
COUNTRY_CHOICES = (
('FR', _(u'France')),
('VE', _(u'Venezuela')),
)
code = models.CharField(max_length=2, choices=COUNTRY_CHOICES)
def __unicode__(self):
return self.get_code_display()
And I would like to do something like:
Country.objects.filter(get_code_display__icontains="france")
Country.objects.filter(code__display__icontains="france")
Country.objects.filter(get_code_display__icontains="france")
But none of those above are working. How do you filter on a field that has a choices
attribute? I thought the overridden __unicode__
would help but I guess I'm missing something.
You can't do this. filter
works at the database level, and the database doesn't know anything about your long names. If you want to do filtering on a value, you need to store that value in the database.
An alternative is to translate the value back into the code, and filter on that:
country_reverse = dict((v, k) for k, v in COUNTRY_CHOICES)
Country.objects.filter(code=country_reverse['france'])
You can swap values in constructor:
class PostFilter(django_filters.FilterSet):
def __init__(self, data=None, queryset=None, prefix=None, strict=None):
data = dict(data)
if data.get('type'):
data['type'] = Post.get_type_id(data['type'][0])
super(PostFilter, self).__init__(data, queryset, prefix, strict)
class Meta:
model = Post
fields = ['type']
You can use Choices
from model_utils import Choices
class Country(models.Model):
COUNTRY_CHOICES = Choices((
('FR', _(u'France')),
('VE', _(u'Venezuela')),
))
code = models.CharField(max_length=2, choices=COUNTRY_CHOICES)
And make a query:
Country.objects.filter(code=Country.COUNTRY_CHOICES.france)
Inspired from this answer, I did the following:
search_for = 'abc'
results = (
[
x for x, y in enumerate(COUNTRY_CHOICES, start=1)
if search_for.lower() in y[1].lower()
]
)
Country.objects.filter(code__in=results)