使用 django-filter,有没有一种快速的方法来支持所有可能的字段查找?

With django-filter, is there a quick way to support all possible lookups for fields?

django-filter 允许您轻松声明模型的可过滤字段。

例如,

class UserFilter(django_filters.FilterSet):
    class Meta:
        model = User
        fields = ['username']

username 字段提供 exact 查找,相当于此...

class UserFilter(django_filters.FilterSet):
    class Meta:
        model = User
        fields = {
            'username': ['exact']
        }

我正在寻找一种方法来支持给定字段的所有可能的查找过滤器,这样我就不必这样做了:

class UserFilter(django_filters.FilterSet):
    class Meta:
        model = User
        fields = {
            "username": ["exact", "iexact", "contains", "icontains", "startswith", ..., etc.]
        }

您可以通过 django lookup up api

获取字段的所有可能查找
lookups_list = []

lookups = User._meta.get_field("username").get_lookups()
for lookup in lookups:
    lookups_list.append(lookup)

lookups_list的结果:

['exact', 'iexact', 'gt', 'gte', 'lt', 'lte', 'in', 'contains', 'icontains', 'startswith', 'istartswith', 'endswith', 'iendswith', 'range', 'isnull', 'regex', 'iregex']

因此您可以在 FilterSet

中使用它

覆盖get_fields(...)class方法FilterSetclass作为,

import django_filters as filters
# If you are using DRF, import `filters` as
# from django_filters import rest_framework as filters


class AnyModelFilter(filters.FilterSet):
    class Meta:
        model = AnyModel
        fields = '__all__'

    <b>@classmethod
    def get_fields(cls):
        fields = super().get_fields()
        for field_name in fields.copy():
            lookup_list = cls.Meta.model._meta.get_field(field_name).get_lookups().keys()
            fields[field_name] = lookup_list
        return fields</b>
def fields_lookups(MyModel):
    lookups = {}

    fields = [x.name for x in MyModel._meta.fields] #<=1) get all fields names
    for field in fields:
        lookups[field] = [*MyModel._meta.get_field(
            field).get_lookups().keys()]            #<=2) add each field to a `dict`and set it vlaue to the lookups
    return lookups


class StatsticsView(ItemsView):
    queryset = MyModel.objects.all()
    serializer_class = StatisticSer

    filterset_fields = fields_lookups(MyModel) #<= ✅

    def get(self, request, *args, **kwargs):
        ....
    def put(self, request, *args, **kwargs):
        ....
    .
    .
    .