问题
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.
回答1:
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'])
回答2:
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']
回答3:
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)
回答4:
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)
来源:https://stackoverflow.com/questions/4727327/django-filter-for-get-foo-display-in-a-queryset