关系
- 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
来源:oschina
链接:https://my.oschina.net/tplinuxhyh/blog/3157596