Django:在查询集中筛选get_foo_display

16 投票
4 回答
8278 浏览
提问于 2025-04-16 10:12

我一直在尝试对一个简单模型的查询结果进行过滤,但到现在为止都没有成功。

这是我的模型:

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()

我想做的事情是:

Country.objects.filter(get_code_display__icontains="france")
Country.objects.filter(code__display__icontains="france")
Country.objects.filter(get_code_display__icontains="france")

但是上面这些都没有奏效。我该如何在一个有choices属性的字段上进行过滤呢?我以为重写__unicode__会有帮助,但我想我还是遗漏了什么。

4 个回答

1

你可以在构造函数中交换值:

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

你可以使用 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)

然后你可以进行查询:

Country.objects.filter(code=Country.COUNTRY_CHOICES.france)
28

你不能这样做。filter 是在数据库层面上工作的,而数据库对你的长名称一无所知。如果你想对某个值进行过滤,你需要把这个值存储在数据库里。

另一种方法是把这个值转换回代码中,然后再进行过滤:

country_reverse = dict((v, k) for k, v in COUNTRY_CHOICES)
Country.objects.filter(code=country_reverse['france'])

撰写回答