首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >测试开发进阶(二十八)

测试开发进阶(二十八)

作者头像
zx钟
发布2019-10-25 00:29:43
7360
发布2019-10-25 00:29:43
举报
文章被收录于专栏:测试游记测试游记

欢迎关注我的公众号「测试游记」

如果前端请求头中没有指定Accept 默认返回json格式的数据

text/html

$ http -v :8000/project/1/ Accept:text/html

application/json

$ http -v :8000/project/1/ Accept:application/json

!返回json

使用GenericAPIView重写ProjectDetail

class ProjectDetail(GenericAPIView):    queryset = Projects.objects.all()    serializer_class = ProjectModelSerializer    def get(self, request, pk):        project = self.get_object()        serializer = self.get_serializer(instance=project)        return Response(serializer.data, status=status.HTTP_200_OK)

从源码中可以看到 GenericAPIView中实现了 get_object方法

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

查看 self.lookup_field可以找到

lookup_field='pk'

进入 get_object_or_404可以看到一个解包,这样就拿到了查询集中 id=1的内容

所以使用 lookup_field类属性,可以修改传入的内容命名

  • 使用 get_serializer获取序列化器

全局指定排序

LearnDjango/settings.py中添加

REST_FRAMEWORK = {    "DEFAULT_RENDERER_CLASSES": (        # json渲染器为第一优先级        "rest_framework.renderers.JSONRenderer",        # 可浏览的API渲染为第二优先级        "rest_framework.renderers.BrowsableAPIRenderer",    ),    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.OrderingFilter']}

过滤

安装

$ pip install django-filter

使用

添加 django_filtersAPP

INSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'rest_framework',    'django_filters',    # 注册子应用    # 子应用名.apps.子应用名首字母大写Config    'projects.apps.ProjectsConfig',    'interfaces.apps.InterfacesConfig',    'corsheaders',]

projects/views.py导入

from django_filters.rest_framework import DjangoFilterBackend

projects.views.ProjectsList添加

# 5.在类视图中指定过滤引擎filter_backends = [DjangoFilterBackend]# 6.指定过滤的字段filterset_fields = ['name', 'leader']

查询

$ http :8000/project/ name=='测试游记1'zhongxindeMacBook-Pro:~ zhongxin$ http :8000/project/ name=='测试游记1'HTTP/1.1 200 OKAllow: GET, POST, HEAD, OPTIONSContent-Length: 130Content-Type: application/jsonDate: Tue, 22 Oct 2019 14:19:31 GMTServer: WSGIServer/0.2 CPython/3.7.1Vary: Accept, Origin, CookieX-Frame-Options: SAMEORIGIN[    {        "desc": "6666",        "id": 2,        "interfaces_set": [],        "name": "测试游记1",        "programer": "zhong1",        "publish_app": "公众号1",        "tester": "zx1"    }]

在全局指定

REST_FRAMEWORK = {    "DEFAULT_RENDERER_CLASSES": (        # json渲染器为第一优先级        "rest_framework.renderers.JSONRenderer",        # 可浏览的API渲染为第二优先级        "rest_framework.renderers.BrowsableAPIRenderer",    ),    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.OrderingFilter',                                'django_filters.rest_framework.DjangoFilterBackend']}

分页

REST_FRAMEWORK = {    "DEFAULT_RENDERER_CLASSES": (        # json渲染器为第一优先级        "rest_framework.renderers.JSONRenderer",        # 可浏览的API渲染为第二优先级        "rest_framework.renderers.BrowsableAPIRenderer",    ),    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.OrderingFilter',                                'django_filters.rest_framework.DjangoFilterBackend'],    # 在全局指定分页的引擎    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',    # 同时必须指定每页显示的条数    'PAGE_SIZE': 3,}

修改 projects.views.ProjectsList#get

def get(self, reuqest):   # 使用get_queryset获取查询集    project_qs = self.get_queryset()     # 使用filter_queryset方法过滤查询    project_qs = self.filter_queryset(project_qs)      # 使用paginate_queryset进行分页,然后返回分页之后的查询集    page = self.paginate_queryset(project_qs)      if page is not None:        serializer = self.get_serializer(instance=page, many=True)        return self.get_paginated_response(serializer.data)    serializer = self.get_serializer(instance=project_qs, many=True)    return Response(serializer.data, status=status.HTTP_200_OK)

分页后

zhongxindeMacBook-Pro:~ zhongxin$ http :8000/project/HTTP/1.1 200 OKAllow: GET, POST, HEAD, OPTIONSContent-Length: 520Content-Type: application/jsonDate: Tue, 22 Oct 2019 14:41:54 GMTServer: WSGIServer/0.2 CPython/3.7.1Vary: Accept, Origin, CookieX-Frame-Options: SAMEORIGIN{    "count": 5,    "next": "http://localhost:8000/project/?page=2",    "previous": null,    "results": [        {            "desc": "666",            "id": 1,            "interfaces_set": [                "Interfaces object (1)",                "Interfaces object (2)"            ],            "name": "测试游记",            "programer": "zhong",            "publish_app": "公众号",            "tester": "zx"        },        {            "desc": "6666",            "id": 2,            "interfaces_set": [],            "name": "测试游记1",            "programer": "zhong1",            "publish_app": "公众号1",            "tester": "zx1"        },        {            "desc": "666",            "id": 3,            "interfaces_set": [],            "name": "「测试游记」-创建",            "programer": "zx",            "publish_app": "公众号",            "tester": "zx"        }    ]}zhongxindeMacBook-Pro:~ zhongxin$

自定义分页

utils.pagination.PageNumberPaginationManual新写一个类继承于 PageNumberPagination

from rest_framework.pagination import PageNumberPaginationclass PageNumberPaginationManual(PageNumberPagination):    page_query_param = 'p'  # url中查询关键字从page修改为p    page_size = 2  # 每页显示的条数为2    max_page_size = 50  # 分页的最大的page_size

在某个类中指定分页

添加

pagination_class = PageNumberPaginationManual

再次优化

借鉴 python3.7/site-packages/rest_framework/mixins.py

查看 rest_framework.mixins.ListModelMixin

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)

发现和 projects.views.ProjectsList#get一样

修改 get

from rest_framework import mixinsclass ProjectsList(mixins.ListModelMixin, GenericAPIView):    def get(self, request, *args, **kwargs):        return self.list(request, *args, **kwargs)

全部优化后:

from projects.models import Projectsfrom projects.serializer import ProjectModelSerializerfrom rest_framework.generics import GenericAPIViewfrom django_filters.rest_framework import DjangoFilterBackendfrom rest_framework import mixinsclass ProjectsList(mixins.ListModelMixin,                   mixins.CreateModelMixin,                   GenericAPIView):    ordering_fields = ['name', 'leader']    queryset = Projects.objects.all()    serializer_class = ProjectModelSerializer    filter_backends = [DjangoFilterBackend]    filterset_fields = ['name', 'leader', 'tester']    def get(self, request, *args, **kwargs):        return self.list(request, *args, **kwargs)    def post(self, request, *args, **kwargs):        return self.create(request, *args, **kwargs)class ProjectDetail(mixins.RetrieveModelMixin,                    mixins.UpdateModelMixin,                    mixins.DestroyModelMixin,                    GenericAPIView):    queryset = Projects.objects.all()    serializer_class = ProjectModelSerializer    def get(self, request, *args, **kwargs):        return self.retrieve(request, *args, **kwargs)    def put(self, request, *args, **kwargs):        return self.update(request, *args, **kwargs)    def delete(self, request, *args, **kwargs):        return self.destroy(request, *args, **kwargs)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • text/html
  • application/json
  • 使用GenericAPIView重写ProjectDetail
  • 全局指定排序
  • 过滤
    • 安装
      • 使用
        • 在全局指定
        • 分页
        • 自定义分页
        • 在某个类中指定分页
        • 再次优化
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档