【问题标题】:Django-filter multiple URL parametersDjango-过滤多个URL参数
【发布时间】:2014-10-01 22:03:49
【问题描述】:

我正在使用Django-filter 应用程序在我的网站上构建搜索。这是代码:

class PropertyFilter(django_filters.FilterSet):
city = django_filters.ModelMultipleChoiceFilter(queryset=City.objects.all(), widget = CheckboxSelectMultiple)
trade_type = django_filters.ModelMultipleChoiceFilter(queryset=Trade.objects.all(), widget = CheckboxSelectMultiple)

class Meta:
    model = Property
    fields = ['city', 'trade_type']

问题在于,当用户标记两个城市时,Django-filter 仅通过最后一个 URL 参数过滤对象(本例中为 2 号城市):

http://example.org/lt/list/city=1&city=2

Models.py:

class City(models.Model):
    name = models.CharField(max_length=250, verbose_name=_('Name'))

也许我做错了什么?

【问题讨论】:

  • 或许http://example.org/lt/list/?city=1,2

标签: python django django-filter


【解决方案1】:

最好的方法是使用来自Django filter DOC 的自定义过滤器 在我的情况下,我使用 (',') 来拆分 url 应该是这样的:

localhost:8000/?city=1,2,3(可以使用字符串值)

    
   class F(django_filters.FilterSet):
         city = CharFilter(method='my_custom_filter')

         class Meta:
            model = Property
            fields = ['city','trade_type']

         def my_custom_filter(self, queryset, name, value):
            value_list = value.split(u',') #split the values by ,
            return queryset.filter(**{
            name+"__in": value_list, #add __in to get each value of the list
            })

【讨论】:

    【解决方案2】:

    您可以让它与您尝试使用的相同 URL 一起工作。按照我的例子。您必须传递要过滤的选项。

    我正在调用的 URL:

    http://example.org/product-list/gender=1&gender=2
    

    filters.py

    GENDER_CHOICES = tuple(
        ProductAttributeOptions.objects.filter(group__name='gender').values_list('id', 'option'))
    
    class ProductFilter(django_filters.FilterSet):        
        gender = django_filters.MultipleChoiceFilter(choices=GENDER_CHOICES,
                                                     method='filter_gender')
    
        def filter_gender(self, qs, name, value):
            result = qs.filter(Q(attribute_values__attribute__name='gender',
                             attribute_values__value_option__in=value))
    
            return result
    
    class Meta:
        model = Product
        fields = ('gender')
    

    希望这会有所帮助。我的灵感来自official docs

    【讨论】:

    • 但你必须事先知道GENDER_CHOICES
    【解决方案3】:

    您可以创建查询字符串的复数版本并接受一个列表作为过滤器参数:

    http://example.org/lt/list/?cities=1,2


    class CustomFilterList(django_filters.Filter):
        def filter(self, qs, value):
            if value not in (None, ''):
                values = [v for v in value.split(',')]
                return qs.filter(**{'%s__%s' % (self.name, self.lookup_type): values})
            return qs
    
    class PropertyFilter(django_filters.FilterSet):
        city = django_filters.ModelMultipleChoiceFilter(queryset=City.objects.all(), widget = CheckboxSelectMultiple)
        trade_type = django_filters.ModelMultipleChoiceFilter(queryset=Trade.objects.all(), widget = CheckboxSelectMultiple)
        cities = CustomFilterList(name="city", lookup_type="in")
    
        class Meta:
            model = Property
            fields = ['cities', 'city', 'trade_type']
    

    查看此答案以正确过滤值列表:

    Possible to do an `in` `lookup_type` through the django-filter URL parser?

    【讨论】:

      猜你喜欢
      • 2015-08-06
      • 2018-04-11
      • 2020-01-10
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多