1 环境
操作系统:
centos 7.6
软件版本:
python 3.8.16
Django 3.2.5
django-rest-framework 3.14.0
2 drf测试应用及数据表初始化
2.1 创建drf 测试应用
# 进入django apps 存放目录
cd project/apps # project 项目目录 apps 应用存放目录
python ../../manage.py startapp app_drf_books
2.2 注册应用
# settings.py
INSTALLED_APPS = [
...
'app_drf_books',
]
2.3 模型创建
# app_drf_books/models.py
from django.db import models
class Books(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
author = models.CharField(max_length=32)
publish = models.CharField(max_length=32)
class Meta:
db_table = 'books'
2.4 数据库迁移
# 生成makemigrations 文件
python manage.py makemigrations
# 文件同步数据库
python manage.py migrate
3 django serializers 序列化
serializers 方式分两种 :模型序列化器和普通序列化器
没有使用ModelSerializer序列化器时,我们自定义的序列化器类需要添加对应模型类中的很多字段,但是如果添加的字段有成百个,是否也需要一个一个手动添加呢?所以有一种更为简洁的模型序列化器类来帮我们优化框架代码,简化序列化器类中字段的创建
普通序列化器类示例:
class ProjectsSerializer(serializers.Serializer):
name = serializers.CharField(max_length=50, label='项目名称', help_text='项目名称帮助文档',validators=[ validators.UniqueValidator(queryset=Project.objects.all(), message="项目名称已存在")])
leader = serializers.CharField(max_length=200, label='项目负责人', help_text='项目负责人帮助文档')
tester = serializers.CharField(max_length=200, label='测试人员', help_text='测试人员帮助文档',
error_messages={"required": "tester该字段必传", "max_length": "长度不能操作5个字节"})
使用模型序列化器类(ModelSerializer)如下:
class ProjectsModelSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
可以看见,已经简化很多,规则总结如下:
-
需要在Meta类中使用model类属性来指定需要按照哪一个模型类来创建
-
fields类属性指定模型类中哪些字段需要输入或输出
-
默认id主键会添加read_only=True
-
create_time和update_time会默认添加read_only=True
-
ModelSerializer类中自带的有create和update方法,无需重写即可生效
3.1 路由配置
该处使用路由分发
# 一级路由
# project/urls.py配置
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path("books/", include("app_drf_books.urls")),
]
# 二级路由
# app_drf_books/urls.py配置
from django.urls import path,re_path
from . import views
urlpatterns = [
path('', views.BooksAPIView.as_view()), # 普通序列化器单本书籍的查,改,删
re_path('(?P<pk>\d+)', views.BookAPIView.as_view()), # 普通序列化器查询全部书籍、增加新书籍
path('m', views.booksView.as_view()), # 模型序列化器
]
3.2 serializers.Serializer 实现
ser.py 序列化器
#app_drf_books/ser.py 序列化器
from rest_framework import serializers
from app_drf_books import models
from rest_framework.exceptions import ValidationError
class BookSerializers(serializers.Serializer):
id = serializers.CharField(read_only=True)
title = serializers.CharField()
price = serializers.CharField()
author = serializers.CharField()
publish = serializers.CharField()
def update(self, instance, validated_data):
instance.title = validated_data.get('title')
instance.price = validated_data.get('price')
instance.author = validated_data.get('author')
instance.publish = validated_data.get('publish')
instance.save()
return instance
def create(self, validated_data):
result = models.Books.objects.create(**validated_data)
return result
def validate_title(self, data):
if 'small baby' in data:
raise ValidationError('书名中不能有敏感字眼哦')
else:
return data
def validate_price(self, data):
if float(data) >= 200:
raise ValidationError('奸商啊,卖那么贵,不让你卖,气死你')
else:
return data
utils.py 自定义工具类
#app_drf_books/utils.py 自定义工具类
class MyResponse():
def __init__(self):
self.code = 100
self.msg = 'OK'
@property
def dict(self):
return self.__dict__
view.py 视图函数,CBV模式
#app_drf_books/view.py 视图函数
from rest_framework.views import APIView
from app_drf_books import models
from app_drf_books.ser import BookSerializers,bookModelSerializers
from app_drf_books import utils
from rest_framework.response import Response
# 单本书籍的查,改,删
class BookAPIView(APIView):
def get(self, request, pk): # 单本书籍的查询
response_dic = utils.MyResponse() # 实例化自定义工具类中的response类
book = models.Books.objects.filter(pk=pk).first() # 获取当前查询图书对象
book_ser = BookSerializers(instance=book) # 实例化自定义序列化器
response_dic.data = book_ser.data # 将数据传入
return Response(response_dic.dict)
def put(self, request, pk): # 单本书籍的修改
response_dic = utils.MyResponse() # 实例化自定义类
book = models.Books.objects.filter(pk=pk).first() # 获取要修改的书籍
book_ser = BookSerializers(instance=book, data=request.data) # 传入要修改的对象和数据
if book_ser.is_valid(): # 校验数据
book_ser.save() # 保存数据,需要在自定义序列化器中重写update方法
response_dic.data = book_ser.data
else:
response_dic.code = 99
response_dic.msg = '校验不通过'
response_dic.data = book_ser.errors # 返回校验结果
return Response(response_dic.dict)
def delete(self, request, pk): # 删除指定图书
response_dic = utils.MyResponse()
models.Books.objects.filter(pk=pk).delete()
return Response(response_dic.dict)
# 查询全部书籍、增加新书籍
class BooksAPIView(APIView):
def get(self, request):
response_dic = utils.MyResponse()
book = models.Books.objects.all() # 获得全部book对象
book_ser = BookSerializers(instance=book, many=True) # 序列化多条数据需要加上many参数
response_dic.data = book_ser.data
return Response(response_dic.dict)
def post(self, request):
response_dic = utils.MyResponse()
book_ser = BookSerializers(data=request.data) # 新增时不需要传入修改对象,传入新增数据
if book_ser.is_valid(): # 校验
book_ser.save()
response_dic.data = book_ser.data
else:
response_dic.code = 99
response_dic.msg = '校验失败'
response_dic.data = book_ser.errors
return Response(response_dic.dict)
3.3 serializers.ModelSerializer实现
ser.py 序列化器
# app_drf_books/ser.py 序列化器
from rest_framework import serializers
from app_drf_books import models
from rest_framework.exceptions import ValidationError
class bookModelSerializers(serializers.ModelSerializer):
class Meta(): #在serializers.ModelSerializer特有
model = models.Books # 左为序列化地址 右为模型
fields = '__all__' # '__all__'表示所有字段,也可以在这之后放入列表来序列化特定的字段
view.py 视图函数,CBV模式
#app_drf_books/view.py 视图函数
from rest_framework.views import APIView
from app_drf_books import models
from app_drf_books.ser import BookSerializers,bookModelSerializers
from app_drf_books import utils
from rest_framework.response import Response
from django.http import JsonResponse
class booksView(APIView):
def get(self,request):
params = request.query_params.get('id')
if params:
res=models.Books.objects.filter(pk=params)
serializer = bookModelSerializers(res, many=True)
return JsonResponse(serializer.data, safe=False)
res_obj = models.Books.objects.all()
serializer = bookModelSerializers(res_obj,many=True)
return JsonResponse(serializer.data,safe=False)
def post(self,request):
params = request.data
serializer = bookModelSerializers(data=params)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
def put(self,request):
params = request.data
id = params.get('id')
res = models.Books.objects.filter(pk=id).first()
serialezers = bookModelSerializers(instance=res,data=params)
if serialezers.is_valid():
serialezers.save()
return JsonResponse(serialezers.data)
def delete(self,request):
params = request.query_params
id = params.get('id')
res = models.Books.objects.filter(pk=id).first()
serializers = bookModelSerializers(instance=res)
res.delete()
return JsonResponse(serializers.data)
4 API接口验证
serializers.Serializer 序列化器查询接口验证
serializers.ModelSerializer 序列化器查询接口验证
参考连接:
https://www.cnblogs.com/hysc/p/14777552.html
https://blog.csdn.net/yhwu123/article/details/107185552