interfaces/serializer.py
中创建序列化器
from rest_framework import serializers
from interfaces.models import Interfaces
class InterfaceModelSerializer(serializers.ModelSerializer):
class Meta:
model = Interfaces
fields = '__all__'
测试
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值
序列化输出
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}
重写 project
project = serializers.StringRelatedField(label='所属项目')
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__
方法返回值)
project = serializers.SlugRelatedField(slug_field='tester')
SlugRelatedField 此字段被序列化为关联对象的指定字段数据
project = serializers.SlugRelatedField(slug_field='name',read_only=True)
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'}
from projects.serializer import ProjectModelSerializer
project = ProjectModelSerializer(label='所属项目', read_only=True)
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
中添加
interfaces_set = serializers.StringRelatedField(many=True)
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'}
from rest_framework.views import APIView
当视图继承 APIView
之后,请求实例方法中的第二个参数 request
为 Request对象
,是对Django中的 HttpRequest对象
进行的拓展
http:8000/project/<projects.json
http-f:8000/project/<projects.form
name=测试游记项目&leader=icon&tester=zhongxin&programer=zhong3&publish_app=公众号&desc=无
根据请求头中的Content-Type自动进行解析 无论前端发送那种格式数据,都可以以相同的方式读取
类似于Django中的request.POST和request.FILES 可以对POST,PUT,PATCH的请求体进行解析 支持form表单传参,支持json格式传参
类似Django中的request.GET 获取查询字符串参数
from rest_framework.response import Response
LearnDjango/settings.py
中添加:
# 指定默认渲染类
REST_FRAMEWORK = {
"DEFAULT_RENDERER_CLASSES": (
# json渲染器为第一优先级
"rest_framework.renderers.JSONRenderer",
# 可浏览的API渲染为第二优先级
"rest_framework.renderers.BrowsableAPIRenderer",
)
}
修改 projects.views.ProjectDetail#get
def get(self, request, pk):
project = self.get_object(pk)
serializer = ProjectSerializer(instance=project)
return Response(serializer.data)
http:8000/project/1/
(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"
}
浏览器中输入:http://127.0.0.1:8000/project/1/
参数
序列化处理后的数据 一般为serializer.data「python基本数据类型:字典,嵌套字典的列表」
状态码,默认200
模版名称,使用HTMLRenderer渲染时需要指明
用于存放响应头信息的字典
响应头中的Content-Type 通常此参数无需设置,会自动根据前端所需类型数据来设置该参数
from rest_framework import status
修改 get
def get(self, request, pk):
project = self.get_object(pk)
serializer = ProjectSerializer(instance=project)
return Response(serializer.data, status=status.HTTP_200_OK)
from rest_framework.generics import GenericAPIView
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
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_serializer
和 rest_framework.generics.GenericAPIView#get_serializer_class
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)
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)
一致
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)
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$
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"
}
]