前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >测试开发进阶(二十七)

测试开发进阶(二十七)

作者头像
zx钟
发布2019-10-23 19:21:43
5930
发布2019-10-23 19:21:43
举报
文章被收录于专栏:测试游记

外键

PrimaryKeyRelatedField

interfaces/serializer.py中创建序列化器

代码语言:javascript
复制
from rest_framework import serializers
from interfaces.models import Interfaces


class InterfaceModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Interfaces
        fields = '__all__'

测试

代码语言:javascript
复制
IN[2]: from interfaces.serializer import InterfaceModelSerializer
IN[3]: InterfaceModelSerializer()

Out[4]: 
InterfaceModelSerializer():
    id = IntegerField(label='ID', read_only=True)
    name = CharField(help_text='项目名称', label='项目名称', max_length=200, validators=[<UniqueValidator(queryset=Interfaces.objects.all())>])
    tester = CharField(help_text='测试人员', label='测试人员', max_length=50)
    desc = CharField(allow_blank=True, allow_null=True, help_text='简要描述', label='简要描述', required=False, style={'base_template': 'textarea.html'})
    project = PrimaryKeyRelatedField(help_text='所属项目', label='所属项目', queryset=Projects.objects.all())

数据库模型中的外键字段默认会生产PrimaryKeyRelatedField序列化器字段 序列化输出的值为外键ID值

序列化输出

代码语言:javascript
复制
from interfaces.models import Interfaces
one_interface = Interfaces.objects.get(id=1)
one_interface
Out[7]: <Interfaces: Interfaces object (1)>
interface_serializer = InterfaceModelSerializer(one_interface)
interface_serializer.data
Out[9]: {'id': 1, 'name': '登录接口', 'tester': 'zx', 'desc': '66', 'project': 1}

字符串关联字段StringRelatedField

重写 project

代码语言:javascript
复制
project = serializers.StringRelatedField(label='所属项目')
代码语言:javascript
复制
from interfaces.models import Interfaces
from interfaces.serializer import InterfaceModelSerializer
one = Interfaces.objects.get(id=1)
one_s = InterfaceModelSerializer(one)
one_s.data
Out[6]: {'id': 1, 'project': '测试游记', 'name': '登录接口', 'tester': 'zx', 'desc': '66'}

StringRelatedField 此字段将被序列化为关联对象字符串表达形式( __str__方法返回值)

代码语言:javascript
复制
project = serializers.SlugRelatedField(slug_field='tester')

指定字段数据SlugRelatedField

SlugRelatedField 此字段被序列化为关联对象的指定字段数据

代码语言:javascript
复制
project = serializers.SlugRelatedField(slug_field='name',read_only=True)
代码语言:javascript
复制
from interfaces.serializer import InterfaceModelSerializer
from interfaces.models import Interfaces
one = Interfaces.objects.get(id=1)
one_s = InterfaceModelSerializer(one)
one_s.data
Out[6]: {'id': 1, 'project': '测试游记', 'name': '登录接口', 'tester': 'zx', 'desc': '66'}

关联对象的序列化器

代码语言:javascript
复制
from projects.serializer import ProjectModelSerializer
project = ProjectModelSerializer(label='所属项目', read_only=True)
代码语言:javascript
复制
from interfaces.serializer import InterfaceModelSerializer
from interfaces.models import Interfaces
one = Interfaces.objects.get(id=1)
one_s = InterfaceModelSerializer(one)
one_s.data
Out[6]: {'id': 1, 'project': OrderedDict([('id', 1), ('name', '测试游记'), ('tester', 'zx'), ('programer', 'zhong'), ('publish_app', '公众号'), ('desc', '666')]), 'name': '登录接口', 'tester': 'zx', 'desc': '66'}

反向指定

父表中默认不会生产关联字段(从表),可以手动指定,字段名默认为子表模型类名「小写_set」

projects.serializer.ProjectModelSerializer中添加

代码语言:javascript
复制
interfaces_set = serializers.StringRelatedField(many=True)
代码语言:javascript
复制
from projects.serializer import ProjectModelSerializer
from projects.models import Projects
p = Projects.objects.get(id=1)
ProjectModelSerializer(p).data
Out[5]: {'id': 1, 'name': '测试游记', 'interfaces_set': ['Interfaces object (1)', 'Interfaces object (2)'], 'tester': 'zx', 'programer': 'zhong', 'publish_app': '公众号', 'desc': '666'}

优化视图-请求

代码语言:javascript
复制
from rest_framework.views import APIView

当视图继承 APIView之后,请求实例方法中的第二个参数 requestRequest对象,是对Django中的 HttpRequest对象进行的拓展

发送json

http:8000/project/<projects.json

发送form表单

http-f:8000/project/<projects.form

代码语言:javascript
复制
name=测试游记项目&leader=icon&tester=zhongxin&programer=zhong3&publish_app=公众号&desc=无

Request

  • 对Django中的HttpRequest进行拓展

根据请求头中的Content-Type自动进行解析 无论前端发送那种格式数据,都可以以相同的方式读取

  • request.data

类似于Django中的request.POST和request.FILES 可以对POST,PUT,PATCH的请求体进行解析 支持form表单传参,支持json格式传参

  • request.query_params

类似Django中的request.GET 获取查询字符串参数

  • 支持Django.request中所有的对象和方法

优化视图-渲染

代码语言:javascript
复制
from rest_framework.response import Response

LearnDjango/settings.py中添加:

代码语言:javascript
复制
# 指定默认渲染类
REST_FRAMEWORK = {
    "DEFAULT_RENDERER_CLASSES": (
        # json渲染器为第一优先级
        "rest_framework.renderers.JSONRenderer",
        # 可浏览的API渲染为第二优先级
        "rest_framework.renderers.BrowsableAPIRenderer",
    )
}

修改 projects.views.ProjectDetail#get

代码语言:javascript
复制
def get(self, request, pk):
    project = self.get_object(pk)
    serializer = ProjectSerializer(instance=project)
    return Response(serializer.data)

渲染1

http:8000/project/1/

代码语言:javascript
复制
(LearnDjango) zhongxindeMacBook-Pro:apitest zhongxin$ http :8000/project/1/
HTTP/1.1 200 OK
Allow: GET, PUT, DELETE, HEAD, OPTIONS
Content-Length: 120
Content-Type: application/json
Date: Fri, 18 Oct 2019 13:34:44 GMT
Server: WSGIServer/0.2 CPython/3.7.1
Vary: Accept, Origin, Cookie
X-Frame-Options: SAMEORIGIN

{
    "desc": "666",
    "id": 1,
    "leader": "zx_94",
    "name": "测试游记",
    "programer": "zhong",
    "publish_app": "公众号",
    "tester": "zx"
}

渲染2

浏览器中输入:http://127.0.0.1:8000/project/1/

Response

参数

  • data

序列化处理后的数据 一般为serializer.data「python基本数据类型:字典,嵌套字典的列表」

  • status

状态码,默认200

  • template_name

模版名称,使用HTMLRenderer渲染时需要指明

  • headers

用于存放响应头信息的字典

  • content_type

响应头中的Content-Type 通常此参数无需设置,会自动根据前端所需类型数据来设置该参数

状态码

代码语言:javascript
复制
from rest_framework import status

修改 get

代码语言:javascript
复制
def get(self, request, pk):
    project = self.get_object(pk)
    serializer = ProjectSerializer(instance=project)
    return Response(serializer.data, status=status.HTTP_200_OK)

支持分页,排序的父类GenericAPIView

代码语言:javascript
复制
from rest_framework.generics import GenericAPIView
  1. 在视图类中指定过滤引擎
  2. 指定需要排序的字段
  3. 指定查询集
  4. 指定模型序列化器
代码语言:javascript
复制
class ProjectsList(GenericAPIView):
    # 1.在视图类中指定过滤引擎
    # OrderingFilter排序
    filter_backends = [filters.OrderingFilter]
    # 2.指定需要排序的字段
    ordering_fields = ['name', 'leader']
    # 3.指定查询集
    queryset = Projects.objects.all()
    # 4.指定模型序列化器
    serializer_class = ProjectModelSerializer

查看 rest_framework.generics.GenericAPIView#get_queryset

代码语言:javascript
复制
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

所以:project_qs=Projects.objects.all()project_qs=self.get_queryset()一致

查看 rest_framework.generics.GenericAPIView#get_serializerrest_framework.generics.GenericAPIView#get_serializer_class

代码语言:javascript
复制
def get_serializer(self, *args, **kwargs):
    """
    Return the serializer instance that should be used for validating and
    deserializing input, and for serializing output.
    """
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()
    return serializer_class(*args, **kwargs)
代码语言:javascript
复制
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=ProjectSerializer(instance=project_qs,many=True)serializer=self.get_serializer(instance=project_qs,many=True)一致

本轮优化后的视图

代码语言:javascript
复制
from django.http import Http404
from projects.models import Projects
from projects.serializer import ProjectSerializer, ProjectModelSerializer
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import status, filters


class ProjectsList(GenericAPIView):
    # 1.在视图类中指定过滤引擎
    # OrderingFilter排序
    filter_backends = [filters.OrderingFilter]
    # 2.指定需要排序的字段
    ordering_fields = ['name', 'leader', 'id']
    # 3.指定查询集
    queryset = Projects.objects.all()
    # 4.指定模型序列化器
    serializer_class = ProjectModelSerializer

    def get(self, reuqest):
        project_qs = self.get_queryset()
        project_qs = self.filter_queryset(project_qs)
        serializer = self.get_serializer(instance=project_qs, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request):
        serializer = ProjectSerializer(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
        except Exception as e:
            return Response(serializer.errors)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)


class ProjectDetail(APIView):
    def get_object(self, pk):
        try:
            return Projects.objects.get(id=pk)
        except Projects.DoesNotExist:
            raise Http404

    def get(self, request, pk):
        project = self.get_object(pk)
        serializer = ProjectSerializer(instance=project)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def put(self, request, pk):
        project = self.get_object(pk)
        serializer = ProjectSerializer(instance=project, data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
        except Exception as e:
            return Response(serializer.errors)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def delete(self, request, pk):
        project = self.get_object(pk)
        project.delete()
        return Response({}, status=status.HTTP_204_NO_CONTENT)

正序

代码语言:javascript
复制
zhongxindeMacBook-Pro:~ zhongxin$ http :8000/project/?ordering=id
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 711
Content-Type: application/json
Date: Fri, 18 Oct 2019 14:14:51 GMT
Server: WSGIServer/0.2 CPython/3.7.1
Vary: Accept, Origin, Cookie
X-Frame-Options: SAMEORIGIN

[
    {
        "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"
    },
    {
        "desc": "「测试游记」",
        "id": 7,
        "interfaces_set": [],
        "name": "1015项目",
        "programer": "zhong2",
        "publish_app": "公众号2",
        "tester": "zx"
    },
    {
        "desc": "无",
        "id": 8,
        "interfaces_set": [],
        "name": "测试游记项目",
        "programer": "zhong3",
        "publish_app": "公众号",
        "tester": "zhongxin"
    }
]

zhongxindeMacBook-Pro:~ zhongxin$

倒序

代码语言:javascript
复制
zhongxindeMacBook-Pro:~ zhongxin$ http :8000/project/?ordering=-id
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 711
Content-Type: application/json
Date: Fri, 18 Oct 2019 14:15:51 GMT
Server: WSGIServer/0.2 CPython/3.7.1
Vary: Accept, Origin, Cookie
X-Frame-Options: SAMEORIGIN

[
    {
        "desc": "无",
        "id": 8,
        "interfaces_set": [],
        "name": "测试游记项目",
        "programer": "zhong3",
        "publish_app": "公众号",
        "tester": "zhongxin"
    },
    {
        "desc": "「测试游记」",
        "id": 7,
        "interfaces_set": [],
        "name": "1015项目",
        "programer": "zhong2",
        "publish_app": "公众号2",
        "tester": "zx"
    },
    {
        "desc": "666",
        "id": 3,
        "interfaces_set": [],
        "name": "「测试游记」-创建",
        "programer": "zx",
        "publish_app": "公众号",
        "tester": "zx"
    },
    {
        "desc": "6666",
        "id": 2,
        "interfaces_set": [],
        "name": "测试游记1",
        "programer": "zhong1",
        "publish_app": "公众号1",
        "tester": "zx1"
    },
    {
        "desc": "666",
        "id": 1,
        "interfaces_set": [
            "Interfaces object (1)",
            "Interfaces object (2)"
        ],
        "name": "测试游记",
        "programer": "zhong",
        "publish_app": "公众号",
        "tester": "zx"
    }
]
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-18,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 外键
    • PrimaryKeyRelatedField
      • 字符串关联字段StringRelatedField
        • 指定字段数据SlugRelatedField
          • 关联对象的序列化器
            • 反向指定
            • 优化视图-请求
              • 发送json
                • 发送form表单
                  • Request
                  • 优化视图-渲染
                    • 渲染1
                      • 渲染2
                        • Response
                        • 状态码
                        • 支持分页,排序的父类GenericAPIView
                        • 本轮优化后的视图
                          • 正序
                            • 倒序
                            相关产品与服务
                            文件存储
                            文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档