简体   繁体   English

Django:在Queryset中过滤get_foo_display

[英]Django: Filter for get_foo_display in a Queryset

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? 如何过滤具有choices属性的字段? I thought the overridden __unicode__ would help but I guess I'm missing something. 我认为被覆盖的__unicode__会有所帮助,但我想我错过了什么。

You can't do this. 你不能这样做。 filter works at the database level, and the database doesn't know anything about your long names. filter在数据库级别工作,并且数据库对您的长名称一无所知。 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']

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)

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM