一、示例

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. 基环树DP

    基环树DP Page1:问题 啥是基环树?就是在一棵树上增加一条边. Page2:基环树的几种情况 无向 有向:基环外向树,基环内向树. Page3:处理问题的基本方式 1.断环成树 2.分别处理树和 ...

  2. 【Gamma】“北航社团帮”发布说明——小程序v3.0

    目录 Gamma版本新功能 小程序v3.0新功能 新功能列表 新功能展示 这一版修复的缺陷 Gamma版本的已知问题和限制 小程序端 网页端 运行.安装与发布 运行环境的要求 安装与发布 小程序 网页 ...

  3. nginx+keepalived高可用及双主模式【h】

    高可用有2中方式. 1.Nginx+keepalived 主从配置 这种方案,使用一个vip地址,前端使用2台机器,一台做主,一台做备,但同时只有一台机器工作,另一台备份机器在主机器不出现故障的时候, ...

  4. vue学习笔记01

    使用vscode配置vue项目 因为之前我没有接触过vue.js,以前的网页也是用Thymeleaf或者jsp写的,这次要求用vscode写vue,感觉现在前端招聘需求量最大的也是这个技术,刚好自己也 ...

  5. SpringBoot扩展点之二:ApplicationRunner和CommandLineRunner的扩展

    CommandLineRunner并不是Spring框架原有的概念,它属于SpringBoot应用特定的回调扩展接口: public interface CommandLineRunner { /** ...

  6. Apache信息头

    package org.apache.http; public final class HttpHeaders { public static final String ACCEPT = " ...

  7. 62 网络编程(三)——UDP编程

    UDP编程标准步骤 服务器端 使用DatagramSocket创建服务端:DatagramSocket server = new DatagramSocket(port);//参数为自定义端口号 准备 ...

  8. 移相器——K波段有源移相器设计

    博主之前在做一款K波段有源移相器,所用工艺为smic55nmll工艺,完成了几个主要模块的仿真,现对之前的工作做个总结. K波段的频率范围是18G——27GHz,所设计移相器的工作频率范围是19G—— ...

  9. -Shell 教程 Bash 脚本 基础语法 MD

    目录 目录 Shell 简介 Shell 脚本 Shell 环境 第一个shell脚本 Shell 变量 定义变量 使用变量 只读变量 删除变量 Shell 字符串 单引号 双引号 字符串基本操作 S ...

  10. C# 调用Access数据库关于like模糊查询的写法

    在access查询视图中要使用"*"做模糊匹配,但是在程序中要用%来匹配.在access中:NEIBUBH like '*1234*'在程序中:NEIBUBH like '%123 ...