江门网站制作开发,湖北网站定制开发多少钱,建立网站wordpress,设计平台属性文章目录 一、概述二、安装三、序列化与反序列化介绍四、之前常用三种序列化方式jsonDjango内置Serializers模块Django内置JsonResponse模块 五、DRF序列化器序列化器工作流程序列化#xff08;读数据#xff09;反序列化#xff08;写数据#xff09; 序列化器常用方法与属… 文章目录 一、概述二、安装三、序列化与反序列化介绍四、之前常用三种序列化方式jsonDjango内置Serializers模块Django内置JsonResponse模块 五、DRF序列化器序列化器工作流程序列化读数据反序列化写数据 序列化器常用方法与属性序列化器参数扩展验证规则局部钩子validate_字段名(self, 字段值)全局钩子validate(self, 所有校验的数据字典) 序列化器支持三种类型Serializer创建应用myapp注册myapp定义数据模型并同步数据库定义序列化器视图里使用序列化器定义路由启动项目实现POST方法获取单个用户更新用户删除用户 ModelSerializer[推荐使用]Meta类常用属性示例 HyperModelSerializer 关联表显示定义数据模型myapp/models.py)定义序列化器myapp/serializers.py)定义视图myapp/views.py)定义路由myapp/urls.py)创建数据库表启动Django项目插入测试数据显示外键对应的详细信息方法一方法二 序列化器SerializerMethodField示例给项目API增加一个字段这个字段数据可从别的表中获取 改变序列化和反序列化的行为示例1示例2希望给返回的数据添加一个统计应用数量的字段 参考 一、概述
Django REST framework 简称DRF是一个强大而灵活的 Web API 工具。遵循RESTFullAPI风格功能完善。
能简化序列化及开发REST API视图的代码大大提高REST API的开发速度;提供灵活的路由API内置了强大的认证和授权机制
二、安装
Django REST framework 最新版使用要求
pip install djangorestframework在settings.py文件的INSTALLED_APPS添加rest_framework
三、序列化与反序列化介绍
序列化将python对象转json 反序列化将json转为python对象
四、之前常用三种序列化方式
json
import json
# 序列化
computer {主机:5000,显示器:1000,鼠标:60,键盘:150}
json.dumps(computer)
# 反序列化
json.loads(json_obj)Django内置Serializers模块
是Django内置的一个序列化器可直接将Python QuerySet对象转为JSON格式但不支持反序列化
from django.core import serializers
obj User.objects.all()
data serializers.serialize(json
, obj)Django内置JsonResponse模块
JsonResponse模块自动将Python对象转为JSON对象并响应。
res {code: 200, msg: 查询成功}
return JsonResponse(res)五、DRF序列化器
DRF中有一个serializers模块专门负责数据序列化DRF提供的方案更先进、更高级别的序列化方案。
序列化器工作流程
序列化读数据
视图里通过ORM从数据库获取数据查询集对象 - 传入序列化器- 序列化器将数据进行序列化 - 调用序列化器的.data获取数据 - 返回前端
反序列化写数据
视图获取前端提交的数据 - 传入序列化器 - 调用序列化器的.is_valid方法进行效验 - 调用序列化器的.save()方法保存数据
序列化器常用方法与属性
serializer.is_valid()调用序列化器验证是否通过传入raise_exceptionTrue可以在验证失败时由DRF响应400异常。serializer.errors获取反序列化器验证的错误信息serializer.data获取序列化器返回的数据serializer.save()将验证通过的数据保存到数据库ORM操作
序列化器参数 示例
class UserSerializer(serializers.Serializer):# 这里的字段必须与使用模型的字段对应id serializers.IntegerField(read_onlyTrue)name serializers.CharField(max_length30,error_messages{ # 设置错误提示blank: 请输入姓名,required: 该字段必要,max_length: 字符长度不超过30,})扩展验证规则
如果常用参数无法满足验证要求时可通过钩子方法扩展验证规则
局部钩子validate_字段名(self, 字段值)
class UserSerializer(serializers.Serializer):…………# 局部钩子# 姓名不能包含数字def validate_name(self, attrs): # attrs是该字段的值from re import findallif findall(\d, attrs):raise serializers.ValidationError(姓名不能包含数字)else:return attrs在视图函数里面通过如下方法查看异常信息
user_ser UserSerializer(datarequest.data)
print(user_ser.errors)效果如下
全局钩子validate(self, 所有校验的数据字典)
class UserSerializer(serializers.Serializer):…………# 全局钩子def validate(self, attrs): # attrs是所有字段组成的字典sex attrs.get(sex)if sex not in [男,女]:raise serializers.ValidationError(性别只能为男或者女)else:return attrs序列化器支持三种类型
• Serializer对Model数据模型进行序列化需自定义字段映射。 • ModelSerializer对Model进行序列化会自动生成字段和验证规则默认还包含简单的create()和update()方法。 • HyperlinkedModelSerializer与ModelSerializer类似只不过使用超链接来表示关系而不是主键ID
Serializer
创建应用myapp
python manage.py startapp myapp注册myapp
在settings.py文件的INSTALLED_APPS添加myapp
定义数据模型并同步数据库
myapp/models.py
from django.db import models# Create your models here.
class User(models.Model):name models.CharField(max_length30)city models.CharField(max_length30)sex models.CharField(max_length10)age models.IntegerField()python manage.py makemigrations python manage.py migrate
定义序列化器
创建myapp_api/serializers.py
from rest_framework import serializersclass UserSerializer(serializers.Serializer):# 这里的字段必须与使用模型的字段对应id serializers.IntegerField()name serializers.CharField(max_length30)city serializers.CharField(max_length30)sex serializers.CharField(max_length10)age serializers.IntegerField()视图里使用序列化器
from myapp.models import User # 导入模型
from .serializers import UserSerializer # 导入序列化器
from rest_framework.views import APIView
from rest_framework.response import Responseclass UserView(APIView):def get(self, requset):queryset User.objects.all() # 获取所有用户# 调用序列化器将queryset对象转换为jsonuser_ser UserSerializer(queryset, manyTrue) # 如果序列化多条数据需要指定manyTruereturn Response(user_ser.data) # 从.data属性获取序列化结果定义路由
test01(项目名)/urls.py
from django.contrib import admin
from django.urls import path,re_path,includeurlpatterns [path(admin/, admin.site.urls),re_path(myapp/, include(myapp.urls)),
]myapp_api/urls.py
from django.urls import re_path
from myapp import viewsurlpatterns [re_path(^api/user/$, views.UserView.as_view()),
]启动项目
访问地址http://127.0.0.1:8001/myapp/api/user/可以查看数据 现在数据库是空的下面写一个POST方法来实现数据的创建
实现POST方法
myapp/views.py,在class UserView的get方法下面增加post方法
def post(self, request):user_ser UserSerializer(datarequest.data) # 调用序列化器将传入的数据反序列化转换为Python对象if user_ser.is_valid(): # 验证数据格式是否正确user_ser.save() # 保存数据到数据库msg 创建用户成功code 200else:msg 数据格式不正确code 400res {code: code, msg: msg}return Response(res)在myapp/serializers.py下面增加如下方法
from myapp.models import User
def create(self, validated_data): # validated_data为提交的JSON数据return User.objects.create(**validated_data)刷新页面发现下面多了个输入框右下角有POST按钮 输入JSON数据点击POST 返回创建成功 再次查看发现多了条数据 再添加几条数据结果如下 上面的方法是查看所有用户那么如何查看单个用户呢
获取单个用户
修改myapp/views.py中的get方法为
def get(self, requset, pkNone):if pk:user_obj User.objects.get(idpk) # 获取单个用户数据user_ser UserSerializer(user_obj)else:queryset User.objects.all() # 获取所有用户# 调用序列化器将queryset对象转换为jsonuser_ser UserSerializer(queryset, manyTrue) # 如果序列化多条数据需要指定manyTrueres {code: 200, msg: 获取用户成功, data: user_ser.data}return Response(res) # 从.data属性获取序列化结果myapp/urls.py增加如下路由
re_path(^api/user/(?Ppk\d)/$, views.UserView.as_view()),效果
更新用户
myapp/views.py,在class UserView的get方法下面增加put方法
def put(self, request, pkNone):user_obj User.objects.get(idpk) # 从数据库查找现有的值#调用序列化器传入已有对象和提交的数据user_ser UserSerializer(instanceuser_obj, datarequest.data)if user_ser.is_valid():user_ser.save()msg 更新用户成功code 200else:msg 更新用户失败数据格式不对code 400res {code: code, msg: msg}return Response(res)在myapp/serializers.py下面增加如下方法
def update(self, instance, validated_data): # instance为当前操作的对象validated_data为提交JSON数据instance.name validated_data.get(name)instance.city validated_data.get(city)instance.sex validated_data.get(sex)instance.age validated_data.get(age)instance.save()return instance实际效果
删除用户
myapp/views.py,在class UserView的get方法下面增加delete方法
def delete(self, request, pkNone):user_obj User.objects.get(idpk)try:user_obj.delete()msg 用户删除成功code 200except Exception as e:msg 用户删除失败code 400res {code: code, msg: msg}return Response(res)效果
ModelSerializer[推荐使用]
ModelSerializer 类型不需要自定义字段映射和定义create、update方法使用起来方便很多
Meta类常用属性
• fields显示所有或指定字段 • exclude排除某个字段元组格式不能与fields同时用 • read_only_fields只读字段即只用于序列化不支持修改 • extra_kwargs添加或修改原有的字段参数字典格式 • depth根据关联的数据递归显示一般是多表
示例
class UserSerializer(serializers.ModelSerializer):class Meta:model User # 指定数据模型fields __all__ # 显示所有字段#exclude (id, ) # 排除字段read_only_fields (id, )extra_kwargs {name: {max_length: 30, requierd: True},city: {max_length: 10, requierd: True},age: {max_length: 30, requierd: True},sex: {mix_value: 16, max_value: 100, requierd: True},}HyperModelSerializer
与MedelSerializer使用方法一样。只不过它使用超链接来表示关系而不是主键ID。
# 更改序列化器
class UserSerializer(serializers.HyperlinkedModelSerializer):class Meta:model Userfields __all__
# 更改视图
user_ser UserSerializer(queryset, manyTrue, context{request: request})
# 更改路由
re_path(^api/user/$, views.UserView.as_view(), nameuser-detail),
re_path(^api/user/(?Ppk\d)/$, views.UserView.as_view(), nameuser-detail)关联表显示
例如应用发布系统项目涉及表 一对多一个项目有多个应用一个应用只能属于一个项目 多对多一个应用部署到多台服务器一个服务器部署多个应用
定义数据模型myapp/models.py)
from django.db import models# 项目表
class Project(models.Model):name models.CharField(max_length30)# 应用表
class App(models.Model):name models.CharField(max_length30)project models.ForeignKey(Project, on_deletemodels.CASCADE) # 一对多# 服务器表
class Server(models.Model):hostname models.CharField(max_length30)ip models.GenericIPAddressField()app models.ManyToManyField(App) # 多对多定义序列化器myapp/serializers.py)
from rest_framework import serializers
from myapp.models import Project, App, Serverclass ProjectSerializer(serializers.ModelSerializer):class Meta:model Projectfields __all__class AppSerializer(serializers.ModelSerializer):class Meta:model Appfields __all__class ServerSerializer(serializers.ModelSerializer):class Meta:model Serverfields __all__定义视图myapp/views.py)
from rest_framework.views import APIView
from rest_framework.response import Response
from myapp.models import Project, App, Server
from .serializers import ProjectSerializer, AppSerializer, ServerSerializerclass ProjectView(APIView):def get(self, request):queryset Project.objects.all() # 获取所有用户project_ser ProjectSerializer(queryset, manyTrue)res {code: 200, msg: 获取用户成功, data: project_ser.data}return Response(res) # 从.data属性获取序列化结果def post(self, requset):project_ser ProjectSerializer(datarequset.data)project_ser.is_valid(raise_exceptionTrue)project_ser.save()return Response(dataproject_ser.data)class AppView(APIView):def get(self, request):queryset App.objects.all() # 获取所有用户app_ser AppSerializer(queryset, manyTrue)res {code: 200, msg: 获取用户成功, data: app_ser.data}return Response(res) # 从.data属性获取序列化结果def post(self, requset):app_ser AppSerializer(datarequset.data)app_ser.is_valid(raise_exceptionTrue)app_ser.save()return Response(dataapp_ser.data)class ServerView(APIView):def get(self, request):queryset Server.objects.all() # 获取所有用户server_ser AppSerializer(queryset, manyTrue)res {code: 200, msg: 获取用户成功, data: server_ser.data}return Response(res) # 从.data属性获取序列化结果def post(self, requset):server_ser ServerSerializer(datarequset.data)server_ser.is_valid(raise_exceptionTrue)server_ser.save()return Response(dataserver_ser.data)定义路由myapp/urls.py)
from django.urls import re_path
from myapp import viewsurlpatterns [re_path(^api/project/$, views.ProjectView.as_view()),re_path(^api/app/$, views.AppView.as_view()),re_path(^api/server/$, views.ServerView.as_view()),
]创建数据库表
python manage.py makemigrations
python manage.py migrate启动Django项目
插入测试数据
打开python控制台
#创建项目
from myapp.models import Project, App, Server
Project.objects.create(name电商)
Project.objects.create(name教育)
#创建应用并指定项目
project_obj Project.objects.get(name电商)
App.objects.create(nameportal, projectproject_obj)
App.objects.create(namegateway, projectproject_obj)
#创建服务器
Server.objects.create(hostnametest1, ip192.168.31.10)
Server.objects.create(hostnametest2, ip192.168.31.11)
#将应用部署到服务器
app_obj App.objects.get(nameportal)
server_obj Server.objects.get(hostnametest1)
server_obj.app.add(app_obj)结果如下
显示外键对应的详细信息
序列化器返回的是当前模型中的字段如果字段是外键时返回的是外键对应id。如下图所示 有两种解决方法
方法一
定义字段为外键对应序列化类这种适合针对某个外键字段 例如
projectProjectSerializer(read_onlyTrue) # 一对多
app AppSerializer(manyTrue) # 多对多方法二
序列化类中Meta类启用depth深度获取关联表数据这种所有外键都会显示出来 效果如下
序列化器SerializerMethodField
DRF序列化器默认仅返回数据模型中已存在资源如果想新增返回字段或者二次处理该 如何操作呢用SerializerMethodFiled
示例给项目API增加一个字段这个字段数据可从别的表中获取
class ProjectSerializer(serializers.ModelSerializer):app_count serializers.SerializerMethodFieldclass Meta:model Projectfields __all__# get_字段名def get_app_count(self, obj):return len(obj.app_get.all())改变序列化和反序列化的行为
可以通过重写下面两个方法改变序列化和反序列化的行为 • to_internal_value()处理反序列化的输入数据自动转换Python对象方便处理。 • to_representation()处理序列化数据的输出
示例1
如果提交API的数据与序列化器要求的格式不符合序列化器就会出现错误。 这时就可以重写to_internal_value()方法只提取出我们需要的数据
示例2希望给返回的数据添加一个统计应用数量的字段 参考
https://www.aliangedu.cn/course/learn?cid20sid10pid2197