您的当前位置:首页正文

四:Django drf url views&分页

2024-11-26 来源:个人技术集锦

分页:

        上篇吧分页漏掉了,这次补上,drf自带的分页不能满足我们的需求,需要我们自定义

        如果不传page_size就不会触发分页,默然返回全部,也符合我的需求

from rest_framework.pagination import PageNumberPagination
from rest_framework.utils.urls import replace_query_param
from rest_framework.response import Response
from collections import OrderedDict
from util import codes
from util import message


# 定制分页
class ZkysPagination(PageNumberPagination):
    """
    @description  :最少提交page_size参数才会分页
    ---------
    @param  :
    -------
    @Returns  :
    -------
    """
    # page_size = 10  # 每页显示多少个
    page_size_query_param = 'page_size'
    page_query_param = 'page'  # 查询参数的名称。默认是’page‘
    max_page_size = 100
    ordered = ['id']

    def get_num_pages_link(self):
        url = self.request.build_absolute_uri()
        num_pages = self.page.paginator.num_pages
        return [replace_query_param(url, self.page_query_param, page) for page in range(1, num_pages + 1)]

    def get_paginated_response(self, data):
        return Response(OrderedDict([
            ('code', codes.normal_code),
            ('msg', message.normal_code),
            ('count', self.page.paginator.count),
            ('num_pages', self.page.paginator.num_pages),  # 分页的总页码
            ('next', self.get_next_link()),
            ('previous', self.get_previous_link()),
            ('pages', self.get_num_pages_link()),  # 所有分页的链接
            ('results', data)
        ]))

Django视图函数编写 

url:

from django.urls import path
from zklf_wtg import views


urlpatterns = [
    path('api/v1/blade_number/', views.BladeNumber.as_view({'get': 'list', 'post': '_create', 'put': "_update"}))
]

views:

list方法是重写的mixins.ListModelMixin,重写list方法可以让我们自己修改序列化的结果,以达到自定义的目的,drf提供的方法只是能满足很基本的需求,很多都是要我们自己重新定义的,也符合框架的理念。

 views.APIView

# 只实现了身份验证,权限验证,限流等基本的验证方法,可以应用于一般的后端api设计

class APIView(View):

    # The following policies may be set at either globally, or per-view.
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
    parser_classes = api_settings.DEFAULT_PARSER_CLASSES
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
    content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
    metadata_class = api_settings.DEFAULT_METADATA_CLASS
    versioning_class = api_settings.DEFAULT_VERSIONING_CLASS

    # Allow dependency injection of other settings to make testing easier.
    settings = api_settings

    schema = DefaultSchema()

viewsets.GenericViewSet :

可以看到GenericViewSet继承于APIView,在限流,权限,身份等验证的基础上添加了分页,过滤和序列化等高级功能。比较适合开发完善的api

class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    """
    The GenericViewSet class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the `get_object` and `get_queryset` methods.
    """
    pass


class GenericAPIView(views.APIView):
    """
    Base class for all other generic views.
    """
    # You'll need to either set these attributes,
    # or override `get_queryset()`/`get_serializer_class()`.
    # If you are overriding a view method, it is important that you call
    # `get_queryset()` instead of accessing the `queryset` property directly,
    # as `queryset` will get evaluated only once, and those results are cached
    # for all subsequent requests.
    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


class APIView(View):

    # The following policies may be set at either globally, or per-view.
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
    parser_classes = api_settings.DEFAULT_PARSER_CLASSES
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
    content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
    metadata_class = api_settings.DEFAULT_METADATA_CLASS
    versioning_class = api_settings.DEFAULT_VERSIONING_CLASS

    # Allow dependency injection of other settings to make testing easier.
    settings = api_settings

 

完整的api应用,仅供参考

class BladeNumber(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    @description  :
    ---------
    @param  :
    -------
    @Returns  :
    -------
    """
    permission_classes = (MyPermission,)	  # 启动token验证
    queryset = models.BladeNumberTableModel.objects.all()
    # 序列化类
    serializer_class = serializer.BladeNumberTableModelSerializer
    # 过滤,排序
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filter_class = zkys_filter_backend.BladeNumberTableModelFilter  # 过滤类
    pagination_class = ZkysPagination  # 分页器
    # 指定排序的字段
    ordering_fields = ("id", "c_time", "u_time")
    # 默认排序字段
    ordering = ["id"]

    coreapi_fields_get = (
            DocParam(name="analy_model_id", location='query', description='', required=False),
            # DocParam(name="token", location='header', description='token'),
        )
    coreapi_fields_post = (
            DocParam(name="task_id", location='body', description='', required=False),
            DocParam(name="blade_one", location='body', description='', required=False),
            DocParam(name="blade_two", location='body', description='', required=False),
            DocParam(name="blade_three", location='body', description='', required=False),
        )
    coreapi_fields_put = (
            DocParam(name="task_id", location='body', description='', required=False),
            DocParam(name="blade_one", location='body', description='', required=False),
            DocParam(name="blade_two", location='body', description='', required=False),
            DocParam(name="blade_three", location='body', description='', required=False),
            DocParam(name="is_delete", location='body', description='', required=False),
        )

    def list(self, request, *args, **kwargs):
        context = {'code': codes.normal_code, 'msg': message.normal_code}
        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)
        # serialized_data = serializer.data
        # for _ in serialized_data:
        #     _["bucket_name"] = settings.MINIO_PANORAMA_BUCKET
        context["results"] = serializer.data
        return JsonResponse(context)

    def _create(self, request):
        """
        @description  :新增数据
        ---------
        @param  :
        -------
        @Returns  :
        -------
        """
        context = {'code': codes.normal_code, 'msg': message.normal_code}
        verify_data = serializer.BladeNumberTableModelSerializer(data=request.data)
        if verify_data.is_valid():
            save = verify_data.save()
            context["data"] = serializer.BladeNumberTableModelSerializer(instance=save).data
        else:
            context["code"] = codes.validate_param_code
            context["msg"] = message.validate_param_code
            context["data"] = verify_data.errors
        return JsonResponse(context)

    def _update(self, request):
        """
        @description  :更新数据
        ---------
        @param  :
        -------
        @Returns  :
        -------
        """
        context = {'code': codes.normal_code, 'msg': message.normal_code}
        task_id = request.data.get("task_id")
        try:
            model_obj = models.BladeNumberTableModel.objects.get(task_id=task_id)
        except models.BladeNumberTableModel.DoesNotExist:
            context["code"] = codes.id_notexist_code
            context["msg"] = message.id_notexist_code
        else:
            verify_data = serializer.BladeNumberTableModelSerializer(instance=model_obj, data=request.data)
            if verify_data.is_valid():
                save = verify_data.save()
                context["data"] = serializer.BladeNumberTableModelSerializer(instance=save).data
            else:
                context["code"] = codes.validate_param_code
                context["msg"] = message.validate_param_code
                context["data"] = verify_data.errors
        return JsonResponse(context)

显示全文