django在场上的多个过滤器

时间:2015-12-08 21:19:33

标签: python django django-filter django-filters

我正在做一个简单的过滤器 -

filters.py

class TblserversFilter(django_filters.FilterSet):
    name = django_filters.CharFilter(name="servername", lookup_type="exact")

    class Meta:
        model = Tblservers
        fields = ['servername']

如果可能,我想做的是让两个lookup_types与该字段相关联。具体来说,我希望exactcontains,然后根据过滤器以某种方式替换运算符。

name=serverabc将是精确搜索,name~abc将是模糊搜索。

2 个答案:

答案 0 :(得分:2)

您可以执行method_filter,然后使用不同的符号为过滤器查询添加前缀,以获取您在客户端所需的精确和图标以及其他过滤器。

因为代码胜过千言万语:

exact_prefix = '#'
icontains_prefix = '~'


class TblserversFilter(django_filters.FilterSet):
    name = django_filters.MethodFilter(
            action=name_filter)

    def name_filter(self, value):
        if value:
            value_prefix = value[0]

            if value_prefix == exact_prefix:
                return self.filter(name=value)

            elif value_prefix == icontains_prefix:
                return self.filter(name__icontains=value)

            # this can continue for all the types of filters you want
            else:
                return self.filter(name=value)
        else:
            return self.filter(name=value)

    class Meta:
        model = Tblservers
       fields = ['servername']

修改

在django-filter 1.0 MethodFilter was replaced with Filter's method argument中。因此,为v1.0重写的解决方案将遵循(未经测试):

exact_prefix = '#'
icontains_prefix = '~'


class TblserversFilter(django_filters.FilterSet):
    name = django_filters.CharFilter(
            method='name_filter')

    def name_filter(self, qs, name, value):
        if value:
            value_prefix = value[0]

            if value_prefix == exact_prefix:
                return qs.filter(name=value)

            elif value_prefix == icontains_prefix:
                return qs.filter(name__icontains=value)

            # this can continue for all the types of filters you want
            else:
                return qs.filter(name=value)
        else:
            return qs.filter(name=value)

    class Meta:
        model = Tblservers
       fields = ['servername']

答案 1 :(得分:1)

首先,我为无耻的图书馆自我插件道歉。

在某些时候,我试图在django-filters中做类似的事情但是解决方案比预期的要复杂得多。我最终创建了自己的库,用于在Django中进行过滤,它本身支持您正在寻找的确切功能 - django-url-filter。它的API与django-filters非常相似:

print y
Rubén
print y.enconde('utf-8')
Rubén
print y.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
  return codecs.utf_8_decode(input, errors, True)
  UnicodeEncodeError: 'ascii' codec can't encode characters in    position 3-4: ordinal not in range(128)    

请注意,URL看起来会有所不同:

from django import forms
from url_filter.filter import Filter
from url_filter.filtersets import ModelFilterSet

class TblserversFilter(FilterSet):
    name = Filter(form_field=forms.CharField(max_length=15), lookups=['exact', 'contains'])

    class Meta(object):
        model = Tblservers
        fields = ['name', 'servername']

此外,您还需要手动调用过滤器集以过滤查询集:

?name=foo  # exact
?name__exact=foo
?name__contains=foo

URL参数的语法与Django ORM非常相似。 您可以查看文档以获取更多示例。希望它可能有用。