【问题标题】:Django: Filter for get_foo_display in a QuerysetDjango:在查询集中过滤 get_foo_display
【发布时间】:2011-06-11 06:29:36
【问题描述】:

我一直在尝试在一个简单的模型上过滤查询集,但到目前为止没有运气。

这是我的模型:

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__ 会有所帮助,但我想我错过了一些东西。

【问题讨论】:

    标签: python django filter django-queryset choicefield


    【解决方案1】:

    this answer 的启发,我做了以下工作:

    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)
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

        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']
        

        【讨论】:

          【解决方案4】:

          你不能这样做。 filter 在数据库级别工作,数据库对您的长名称一无所知。如果要对某个值进行过滤,则需要将该值存储在数据库中。

          另一种方法是将值转换回代码,并对其进行过滤:

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

          【讨论】:

          • 感谢丹尼尔的回答。
          • 难道 django 不能做些什么来让它变得更容易一些。我认为这将是一个常见的操作
          • django-model-utils 上的Choices 类可以通过这种方式发挥作用。
          猜你喜欢
          • 1970-01-01
          • 2020-08-22
          • 2019-04-15
          • 2011-09-29
          • 2011-02-04
          相关资源
          最近更新 更多