一、示例

restful work 的序列号就类似于 Django 的 Form 表单。

1、api/urls.py

from django.urls import path, re_path
from api.views import UserView, ParserView, RolesView urlpatterns = [
# path('users/', UserView.as_view()),
re_path('(?P<version>[v1|v2]+)/users/', UserView.as_view(), name='api_user'), # 解析 re_path('(?P<version>[v1|v2]+)/roles', RolesView.as_view()), # 序列化 path('parser/', ParserView.as_view(), name='api_parer'),
]
  1. api/views.py
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework import serializers
from app import models
import json class RolesSerializers(serializers.Serializer):
"""序列化类(对应 Role 模型类中字段)"""
id = serializers.IntegerField()
name = serializers.CharField() class RolesView(APIView):
def get(self, request, *args, **kwargs):
# 取出全部
# roles = models.Role.objects.all()
# # 序列化,两个参数,instance:接受Queryset(或者对象) mangy=True表示处理多个对象,mant=False表示处理单个对象
# ser = RolesSerializers(instance=roles, many=True)
# # 转成json格式,ensure_ascii=False表示显示中文,默认为True
# ret = json.dumps(ser.data, ensure_ascii=False) # 取出第一个
role = models.Role.objects.all().first()
ser = RolesSerializers(instance=role, many=False)
ret = json.dumps(ser.data, ensure_ascii=False)
return HttpResponse(ret)
  1. app/models.py
from django.db import models

class UserInfo(models.Model):
USER_TYPE = (
(1, '普通用户'),
(2, 'VIP'),
(3, 'SVIP')
) user_type = models.IntegerField(choices=USER_TYPE)
username = models.CharField(max_length=32)
password = models.CharField(max_length=64) group = models.ForeignKey('UserGroup', on_delete=models.CASCADE, verbose_name='所属组', null=True, blank=True)
roles = models.ManyToManyField('Role', verbose_name='角色') class UserToken(models.Model):
user = models.OneToOneField(UserInfo, on_delete=models.CASCADE)
token = models.CharField(max_length=64) class UserGroup(models.Model):
"""分组"""
name = models.CharField(verbose_name='组名', max_length=64) class Role(models.Model):
"""角色"""
name = models.CharField(max_length=64, verbose_name='角色名')
  1. 访问:http://127.0.0.1:8000/api/v1/roles
{"id": 1, "name": "老板"}

二、进阶

前面我们只序列化了没有关联的字段,对于多选字段、外键以及多对多字段都没有演示,在这里我们还将学习如何自定义一个序列化方法。

1、各个数据表数据:

2、api/urls.py

from django.urls import path, re_path
from api.views import UserView, ParserView, RolesView, UserInfoView urlpatterns = [
# path('users/', UserView.as_view()),
re_path('(?P<version>[v1|v2]+)/users/', UserView.as_view(), name='api_user'), re_path('(?P<version>[v1|v2]+)/roles', RolesView.as_view()), # 序列化
re_path('(?P<version>[v1|v2]+)/info', UserInfoView.as_view()), # 序列化 path('parser/', ParserView.as_view(), name='api_parer'),
]

3、api/views.py

class UserInfoSerializers(serializers.Serializer):
# 多选字段:user_type是choices(1,2,3),显示全称的方法用 get_字段名_display
type = serializers.CharField(source='get_user_type_display')
username = serializers.CharField()
password = serializers.CharField()
# 外键字段: group.name:组的名字
group = serializers.CharField(source="group.name")
# SerializerMethodField(),表示自定义显示
# 然后写一个自定义的方法
rls = serializers.SerializerMethodField() def get_rls(self, row):
"""获取用户所有角色,get_rls 和上面自定义方法名字一致"""
print(row) # UserInfo object (2)
role_obj_list = row.roles.all()
print(role_obj_list) # <QuerySet [<Role: Role object (1)>]>
ret = []
# 获取角色的id和名字
# 以字典的键值对方式显示
for item in role_obj_list:
ret.append({"id": item.id, "name": item.name})
return ret class UserInfoView(APIView):
def get(self, request, *args, **kwargs):
users = models.UserInfo.objects.all()
ser = UserInfoSerializers(instance=users, many=True)
ret = json.dumps(ser.data, ensure_ascii=False)
return HttpResponse(ret)
  1. 访问:http://127.0.0.1:8000/api/v1/info
[{"type": "普通用户", "username": "rose", "password": "123", "group": "一组", "rls": [{"id": 1, "name": "老板"}]}, {"type": "VIP", "username": "john", "password": "123", "group": "二组", "rls": []}, {"type": "SVIP", "username": "hj", "password": "123", "group": "三组", "rls": [{"id": 4, "name": "普通员工"}]}]

总结

  • 多选字段:使用 get_字段名_display 获取字段原始值
  • 外键字段:source="外键名.要获取的字段名"
  • 多对多字段:可通过自定义分实现
  • 自定义方法:mth = serializers.SerializerMethodField(),方法名:get_mth()

三、ModelSerializer

ModelSerializer 效果类似于 Django Form 中的 ModelForm

class UserInfoSerializers(serializers.ModelSerializer):
type = serializers.CharField
group = serializers.CharField(source="group.name")
rls = serializers.SerializerMethodField() def get_rls(self, row):
pass class Meta:
model = models.UserInfo
# fields = '__all__'
fields = ['id','username','password','type','group','rls']

四、depth 控制连表的深度

当表与表之间多个相连,如果只想显示前面几层,可以使用 depth 控制连表的深度:

class UserInfoSerializers(serializers.ModelSerializer):
type = serializers.CharField
group = serializers.CharField(source="group.name")
rls = serializers.SerializerMethodField() def get_rls(self, row):
pass class Meta:
model = models.UserInfo
# fields = '__all__'
fields = ['id','username','password','type','group','rls']
depth = 1 # 控制为 1 层

六、HyperlinkedidentityField 生成 url

序列化关联数据表的相应字段的 url,就像下面这种:

[
{
"id": 1,
"publish": "http://127.0.0.1:8080/api/publish/1",
"name": "红楼梦",
"price": "123.00",
"publish_date": null
},
{
"id": 2,
"publish": "http://127.0.0.1:8080/api/publish/2",
"name": "西游记",
"price": "234.00",
"publish_date": null
}
]

1、api/serializers.py

from rest_framework import serializers
from app import models class UserInfoSerializers(serializers.ModelSerializer):
"""用户个人信息序列化"""
group = serializers.HyperlinkedIdentityField(view_name='gob', lookup_field='group_id', lookup_url_kwarg='pk') class Meta:
model = models.UserInfo
fields = '__all__' class RolesSerializers(serializers.Serializer):
"""序列化类"""
id = serializers.IntegerField()
name = serializers.CharField() class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserGroup
fields = "__all__"

参数:

  • view_name:关联路由 URL 中的 name 参数值,用来反向解析 URL
  • lookup_field:要查找的目标字段,如:group_idUserInfo 模型中的外键字段(即我们要查找的字段)
  • lookup_url_kwarg:关键字参数的名称,该参数对应于查找字段,一般为 pk

2、api/urls.py

from django.urls import path, re_path
from api.views import UserView, ParserView, RolesView, UserInfoView, GroupView urlpatterns = [
re_path('(?P<version>[v1|v2]+)/info/', UserInfoView.as_view()), # 序列化 re_path('(?P<version>[v1|v2]+)/group/(?P<pk>\d+)/', GroupView.as_view(), name='gob'), # 序列化生成url ]

3、api/views.py

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework.parsers import JSONParser, FormParser from .serializers import GroupSerializer, RolesSerializers, UserInfoSerializers from app import models
from django.http import JsonResponse class UserInfoView(APIView):
def get(self, request, *args, **kwargs):
users = models.UserInfo.objects.all()
# 这里必须指定 context,将 request 传递给 UserInfoSerializers
user_ser = UserInfoSerializers(instance=users, many=True, context={'request': request})
return JsonResponse(user_ser.data, safe=False) class GroupView(APIView):
def get(self, request, *args, **kwargs):
# pk = kwargs.get('pk')
# group = models.UserGroup.objects.filter(pk=pk).first()
#
# group_ser = GroupSerializer(instance=group, many=False)
# # ret = json.dumps(ser.data, ensure_ascii=False)
# return JsonResponse(group_ser.data, safe=False)
return HttpResponse('ok')

4、访问:http://127.0.0.1:8000/api/v2/info/

[
{
"id": 1,
'username': 'rose', john/hj
'password': '123',
"group": "http://127.0.0.1:8080/api/group/1",
"roles": [
2,
]
},
{
"id": 2,
'username': 'john',
'password': '123',
"group": "http://127.0.0.1:8080/api/group/2",
"roles": [
1,
]
},
]

七、用户请求数据验证

验证用户请求的数据是否合法

1、api/serializers.py

from rest_framework import serializers

class UserGroupSerializers(serializers.Serializer):
"""用户请求验证"""
title = serializers.CharField()

2、api/views.py

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView from .serializers import GroupSerializer, RolesSerializers, UserInfoSerializers, UserGroupSerializers class UserGroupView(APIView):
"""用户请求验证"""
def post(self, request, *args, **kwargs):
usergroup_ser = UserGroupSerializers(data=request.data)
if usergroup_ser.is_valid():
print(usergroup_ser.validated_data['title'])
else:
print(usergroup_ser.errors)
return HttpResponse('用户提交数据错误')

3、利用 postman 模拟用户请求发送数据

请求方式 post,参数格式 JSON:

当请求的数据为空时,会自动验证数据的合法性:

八、自定义验证规则

你可以自定义验证规则,比如验证用户输入的字段必须以什么开头,必须是邮箱格式等:

1、api/serializers.py

class GroupValidation:
"""自定义验证规则"""
def __init__(self, base):
self.base = base # love def __call__(self, value, *args, **kwargs):
if not value.startswith(self.base):
msg = '标题必须以 %s 开头' % self.base
raise serializers.ValidationError(msg) class UserGroupSerializers(serializers.Serializer):
"""用户请求数据验证"""
# title = serializers.CharField()
title = serializers.CharField(validators=[GroupValidation('love'), ])

2、其余的不变,现在验证规则按照我们设置的走,错误提示也一样:

rest framework 之序列化的更多相关文章

  1. Django Rest framework 之 序列化

    RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...

  2. Django Rest Framework(2)-----序列化详解(serializers)

    REST framework中的序列化类与Django的Form和ModelForm类非常相似.我们提供了一个Serializer类,它提供了一种强大的通用方法来控制响应的输出,以及一个ModelSe ...

  3. Django restful Framework 之序列化与反序列化

    1. 首先在已建好的工程目录下新建app命名为snippets,并将snippets app以及rest_framework app加到工程目录的 INSTALLED_APPS 中去,具体如下: IN ...

  4. Django REST Framework的序列化器是什么?

    # 转载请留言联系 用Django开发RESTful风格的API存在着很多重复的步骤.详细可见:https://www.cnblogs.com/chichung/p/9933861.html 过程往往 ...

  5. Django rest framework之序列化小结

       最近在DRF的序列化上踩过了不少坑,特此结合官方文档记录下,方便日后查阅. [01]前言    serializers是什么?官网是这样的”Serializers allow complex d ...

  6. CAF(C++ actor framework)(序列化之复杂类,分析 还有自己不懂的细思恐极函数实现)(三)

    这里应该是序列化的最后一篇.感觉自己写的不是很好,也一点点在学习.这次就不贴上代码了.代码在github上的announce5.cpp.代码简单,但是分析下去会有细思恐极的感觉! 先看一下几个函数是干 ...

  7. CAF(C++ actor framework)(序列化之结构体,任意嵌套STL)(一)

    User-Defined Data Types in Messages(用户自定义类型)All user-defined types must be explicitly “announced” so ...

  8. django rest framework serializers序列化

    serializers是将复杂的数据结构变成json或者xml这个格式的 serializers有以下几个作用: - 将queryset与model实例等进行序列化,转化成json格式,返回给用户(a ...

  9. django-插件django REST framework,返回序列化的数据

    官网: http://www.django-rest-framework.org 1.安装 pip install djangorestframework 2.在setting.py中注册app 中添 ...

  10. restful framework之序列化组件

    一.Django自带序列化组件 from django.core import serializers def test(request): book_list = Book.objects.all( ...

随机推荐

  1. 元素的alt和title有什么异同?

    ①alt作为图片的替代文字出现,title作为图片的解释文字出现. ②alt属性应用较少,如img.area.input中,title应用较多,如a.form.input.还有div.p这些块级元素都 ...

  2. 【转】30种MySQL索引优化的方法

    第一方面:30种mysql优化sql语句查询的方法       1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by涉及的列上建立索引. 2.应尽量避免在 where ...

  3. BBS项目-01

    目录 BBS项目 BBS开发流程: BBS表格创建: BBS项目 BBS开发流程: BBS项目: 开发流程: 需求分析 草拟一些项目的大致技术点和流程 架构设计 架构师(框架 语言 数据库 缓存数据库 ...

  4. TensorFlow常用激活函数及其特点和用法(6种)详解

    http://c.biancheng.net/view/1911.html 每个神经元都必须有激活函数.它们为神经元提供了模拟复杂非线性数据集所必需的非线性特性.该函数取所有输入的加权和,进而生成一个 ...

  5. 测试之selenium简介

    目录 selenium是什么? 应该具备的知识 Selenium功能特性 Selenium的局限性 Selenium与QTP比较 Selenium工具套件 Selenium集成开发环境(IDE) Se ...

  6. vue监听当前页面的地址变化/路由变化

    转载自: Heap Stack(Pingbook) https://pingbook.top/vue-watch-current-url-route-change/

  7. GEO2R

    GEO2R 是GEO数据库官方提供的一个工具,用于进行差异表达分析. 该工具实现的功能就是将GEO数据库中的数据导入到R语言中,然后进行差异分析,本质是通过以下两个bioconductor上的R包实现 ...

  8. csv文件处理

    读取csv文件 import csv with open('demo.csv', 'r') as fp: reader = csv.reader(fp) titles = next(reader) f ...

  9. jvm参数设置实例

  10. sbt 安装

    此次安装实在windows 下进行的 1.官网下载sbt 2.安装并配置环境变量 path  中添加: 3.更改sbt配置文件 1)修改C:\notos\software\sbt\conf\sbtco ...