java过滤器流程_DRF filter 过滤器实现流程

本文详细介绍了Django Rest Framework中过滤器的工作流程,包括ListModelMixin、GenericAPIView、BaseFilterBackend、SearchFilter、OrderingFilter和DjangoFilterBackend等关键类的作用。通过示例代码展示了如何在views.py中设置和使用过滤器,以及如何自定义过滤器类和参数,以实现对queryset的有效过滤和操作。
摘要由CSDN通过智能技术生成

关系

ListModelMixin

GenericAPIView(views.APIView).filter_queryset(queryset)

drf filters.py

BaseFilterBackend

SearchFilter(BaseFilterBackend)

OrderingFilter(BaseFilterBackend)

DjangoFilterBackend(metaclass=RenameAttributes)# django_filters.rest_framework.backends 官方filterdemo

1.入口queryset = self.filter_queryset(self.get_queryset())

views.py

class RecordView(MyModelViewSet):

"""

user view

"""

queryset = Record.objects.filter(status__gte=0)

permission_classes = (permissions.IsAuthenticated, )

filterset_class = RecordFilter # 定义过滤器

serializer_map = {

'create': AuthorizationRecordCreateSerializer,

}

class ListModelMixin:

"""

List a queryset.

"""

def list(self, request, *args, **kwargs):

queryset = self.filter_queryset(self.get_queryset())

page = self.paginate_queryset(queryset)

if page is not None:

serializer = self.get_serializer(page, many=True)

return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)

return Response(serializer.data)

class GenericAPIView(views.APIView):

queryset = None

serializer_class = None

# If you want to use object lookups other than pk, set 'lookup_field'.

# For more complex lookup requirements override `get_object()`.

lookup_field = 'pk'

lookup_url_kwarg = None

# The filter backend classes to use for queryset filtering

filter_backends = api_settings.DEFAULT_FILTER_BACKENDS

def filter_queryset(self, queryset):

"""

Given a queryset, filter it with whichever filter backend is in use.

You are unlikely to want to override this method, although you may need

to call it either from a list view, or from a custom `get_object`

method if you want to apply the configured filtering backend to the

default queryset.

"""

for backend in list(self.filter_backends):

queryset = backend().filter_queryset(self.request, queryset, self)

return queryset

class DjangoFilterBackend(metaclass=RenameAttributes):

filterset_base = filterset.FilterSet

raise_exception = True

def get_filterset(self, request, queryset, view):

filterset_class = self.get_filterset_class(view, queryset) # 1.获取过滤器类

if filterset_class is None:

return None

kwargs = self.get_filterset_kwargs(request, queryset, view) # 2.获取request.query_params过滤参数, 进行下一步过滤

return filterset_class(**kwargs) # 3.实例化过滤器

def get_filterset_class(self, view, queryset=None):

"""

Return the `FilterSet` class used to filter the queryset.

"""

filterset_class = getattr(view, 'filterset_class', None) # views 用户定义

filterset_fields = getattr(view, 'filterset_fields', None) #

# TODO: remove assertion in 2.1

if filterset_class is None and hasattr(view, 'filter_class'):

utils.deprecate(

"`%s.filter_class` attribute should be renamed `filterset_class`."

% view.__class__.__name__)

filterset_class = getattr(view, 'filter_class', None)

# TODO: remove assertion in 2.1

if filterset_fields is None and hasattr(view, 'filter_fields'):

utils.deprecate(

"`%s.filter_fields` attribute should be renamed `filterset_fields`."

% view.__class__.__name__)

filterset_fields = getattr(view, 'filter_fields', None)

if filterset_class:

filterset_model = filterset_class._meta.model

# FilterSets do not need to specify a Meta class

if filterset_model and queryset is not None:

assert issubclass(queryset.model, filterset_model), \

'FilterSet model %s does not match queryset model %s' % \

(filterset_model, queryset.model)

return filterset_class

if filterset_fields and queryset is not None:

MetaBase = getattr(self.filterset_base, 'Meta', object)

class AutoFilterSet(self.filterset_base):

class Meta(MetaBase):

model = queryset.model

fields = filterset_fields

return AutoFilterSet

return None

def get_filterset_kwargs(self, request, queryset, view): # 从request.query_parmas 获取过滤参数

return {

'data': request.query_params,

'queryset': queryset,

'request': request,

}

def filter_queryset(self, request, queryset, view): # APIView 入口

filterset = self.get_filterset(request, queryset, view)

if filterset is None:

return queryset

if not filterset.is_valid() and self.raise_exception:

raise utils.translate_validation(filterset.errors)

return filterset.qs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值