Django框架的学习笔记

基于Django的REST framework 框架的视图说明(二)

开发环境:Ubuntu16.04+Python3.5x+Pycharm2018.2

包含方法和属性的通用视图基类及扩展类的继承关系

《Django框架的学习笔记》

两个基类

APIView类

GenericAPIView类

本篇主要说明GenericAPIView类
rest_framework.generics.GenericAPIView

继承自APIView,增加了对于列表视图和详情视图可能用到的通用支持方法。通常使用时,可搭配一个或多个Mixin扩展类.

支持定义的属性:

列表视图与详情视图通用:
queryset 列表视图的查询集
serializer_class 视图使用的序列化器

列表视图使用:
pagination_class 分页控制类
filter_backends 过滤控制后端

详情页视图使用:
lookup_field 查询单一数据库对象时使用的条件字段,默认为’pk’
lookup_url_kwarg 查询单一数据时URL中的参数关键字名称,默认与look_field相同

源代码如下:

    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

    # The style to use for queryset pagination.
    pagination_class = api_settings.DEFAULT_PAGINATION_CLASS

支持定义的方法:

列表视图与详情视图通用:

get_queryset(self)
源码如下:

   def get_queryset(self):
        """
        Get the list of items for this view.
        This must be an iterable, and may be a queryset.
        Defaults to using `self.queryset`.

        This method should always be used rather than accessing `self.queryset`
        directly, as `self.queryset` gets evaluated only once, and those results
        are cached for all subsequent requests.

        You may want to override this if you need to provide different
        querysets depending on the incoming request.

        (Eg. return a list of items that is specific to the user)
        """
        assert self.queryset is not None, (
            "'%s' should either include a `queryset` attribute, "
            "or override the `get_queryset()` method."
            % self.__class__.__name__
        )

        queryset = self.queryset
        if isinstance(queryset, QuerySet):
            # Ensure queryset is re-evaluated on each request.
            queryset = queryset.all()
        return queryset

返回视图使用的查询集,是列表视图与详情视图获取数据的基础,默认返回queryset属性,可以重写,例如:

def get_queryset(self):
    user = self.request.user
    return user.accounts.all()      

get_serializer_class(self)

    def get_serializer_class(self):
        """
        Return the class to use for the serializer.
        Defaults to using `self.serializer_class`.

        You may want to override this if you need to provide different
        serializations depending on the incoming request.

        (Eg. admins get full serialization, others get basic serialization)
        """
        assert self.serializer_class is not None, (
            "'%s' should either include a `serializer_class` attribute, "
            "or override the `get_serializer_class()` method."
            % self.__class__.__name__
        )

        return self.serializer_class

返回序列化器类,默认返回serializer_class,可以重写,例如:

def get_serializer_class(self):
    if self.request.user.is_staff:
        return FullAccountSerializer
    return BasicAccountSerializer
    

get_serializer(self, args, **kwargs)
返回序列化器对象,被其他视图或扩展类使用,如果我们在视图中想要获取序列化器对象,可以直接调用此方法。

注意,在提供序列化器对象的时候,REST framework会向对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用。

详情视图使用:

get_object(self)

   def get_object(self):
        """
        Returns the object the view is displaying.

        You may want to override this if you need to provide non-standard
        queryset lookups.  Eg if objects are referenced using multiple
        keyword arguments in the url conf.
        """
        queryset = self.filter_queryset(self.get_queryset())

        # Perform the lookup filtering.
        lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field

        assert lookup_url_kwarg in self.kwargs, (
            'Expected view %s to be called with a URL keyword argument '
            'named "%s". Fix your URL conf, or set the `.lookup_field` '
            'attribute on the view correctly.' %
            (self.__class__.__name__, lookup_url_kwarg)
        )

        filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
        obj = get_object_or_404(queryset, **filter_kwargs)

        # May raise a permission denied
        self.check_object_permissions(self.request, obj)

        return obj

返回详情视图所需的模型类数据对象,默认使用lookup_field参数来过滤queryset。 在试图中可以调用该方法获取详情信息的模型类对象。

若详情访问的模型类对象不存在,会返回404。

def get_object_or_404(queryset, *filter_args, **filter_kwargs):
    """
    Same as Django's standard shortcut, but make sure to also raise 404
    if the filter_kwargs don't match the required types.
    """
    try:
        return _get_object_or_404(queryset, *filter_args, **filter_kwargs)
    except (TypeError, ValueError, ValidationError):
        raise Http404

该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问。

举例:以图书与英雄案例(如水浒传与英雄)


# GET /books/
# url(r'^books/$', views.BookListAPIView.as_view()) 对应的路由
class BookListAPIView(GenericAPIView):
    """
    数据查询集
    """
    queryset = BookInfo.objects.all()  # 数据库查询集
    serializer_class = BookInfoSerializer

    def get(self,request):
        # 数据库查询
        qs = self.get_queryset()
        # 构建序列化器对象,进行序列化操作
        serializer = self.get_serializer(qs,many = True)

        return  Response(serializer.data)

# GET /books/<pk>/
# url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()) 对应的路由
class BookDetailAPIView(GenericAPIView):
    queryset = BookInfo.objects.all()

    serializer_class = BookInfoSerializer


    def get(self,request,pk):
        """
        查询单个
        :param query:
        :return:
        """
        book = self.get_object()
        serializer = self.get_serializer(book)

        return Response(serializer.data)
    原文作者:choulibo
    原文地址: https://segmentfault.com/a/1190000016399884
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞