一.rest_framework介绍
官网网站: https://www.django-rest-framework.org/api-guide/requests/
1.简介
a. 是在django的基础上进行的二次开发
b. 用于构建restful api
c. 简称为DRF框架
2. 特性
a. 提供了强大的Serializer序列化器类,可以高效的进行序列化和反序列化操作
b. 提供了极为丰富的类视图、Mixin扩展类、ViewSet视图集;
c. 提供了直观的Web API界面
d. 多种身份认证和权限认证
e. 强大的排序、过滤、分页、搜索、限流等功能
f. 可扩展性、插件丰富
3.安装
a. pip install djangorestframework
可选 #pip install markdown
可选 #pip install django-filter
b.
INSTALLED_APPS = [
…
‘rest_framework’, ]
二. 实战使用
1.示例一:Serializer类
a. models.py文件
# models.py文件
from django.db import models
class Projects(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200, verbose_name='项目名称', help_text='项目名称', unique=True)
leader = models.CharField(max_length=50, verbose_name='项目负责人', help_text='项目负责人')
tester = models.CharField(max_length=50, verbose_name='测试人员', help_text='测试人员')
programmer = models.CharField(max_length=50, verbose_name='开发人员', help_text='开发人员')
desc = models.TextField(verbose_name='项目简介', help_text='项目简介', blank=True, default='xxx简介', null=True)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
# 执行迁移脚本之后,生成的数据表名默认为 子应用名_模型类名小写
class Meta:
db_table = 'tb_projects'
verbose_name = '项目表'
def __str__(self):
return f"<{self.name}>"
b. serializers.py文件
ProjectSerializses类必须继承serializers.Serializer类
ProjectSerializses类中的字段属性必须与models.py中的对应
# serializers.py文件
from rest_framework import serializers
class ProjectSerializses(serializers.Serializer):
# label对应models模型类中的verbose_name
name = serializers.CharField(max_length=30, label="项目名称", help_text="项目名称")
leader = serializers.CharField(max_length=20, label="项目负责人", help_text="项目负责人",write_only=True,required=False)
tester = serializers.CharField(max_length=20,label="测试人员", help_text="测试人员",error_messages={
"required":"这是必传参数22"})
c. views.py文件
class LoginPage(View):
def get(self,request):
"""
输出所有的项目信息
:param request:
:return:
"""
# 获取查询集—》传给序列化器,对于查询集对象,需要传many=True(对于单个模型类对象则不需要)
qs = Projects.objects.all()
ser = ProjectSerializses(instance=qs,many=True)
result = {
"code": "0", "message": "success", "data": ser.data}
return JsonResponse(result, safe=False)
def post(self, request):
"""
创建项目
:param request:
:return:
"""
# 1.获取请求参数
resquest_data = request.body
try:
# 2. 反序列化输入(将json字符串转化为python字典)
resquest_data = json.loads(resquest_data)
except:
result_data = {
"code": "1", "message": "请求参数有误"}
return JsonResponse(result_data, safe=False, status=200)
ser = ProjectSerializses(data=resquest_data)
try:
# 会将前端传入的参数使用序列化器进行校验
ser.is_valid(raise_exception=True)
except:
# 校验失败可以使用ser.errors进行输出
result_data = {
"code": "2", "message": "请求参数有误","data":ser.errors}
return JsonResponse(result_data, safe=False, status=200)
# 3. 进行数据库操作
Projects.objects.create(**resquest_data)
# 4.序列化输出(将模型类对象转换为json字符串)
# result = {"code": "0", "message": "success", "data": model_to_dict(obj)}
# ser.validated_data是校验前端结束后的数据
# ser.data是从查询集中拿到数据后去除掉,序列化器中没有的以及write_only=True的
result = {
"code": "0", "message": "success", "data": ser.data}
return JsonResponse(result, safe=False)
d. 测试结果
2.示例二:ModelSerializer类及其校验
a.serializers.py文件
def is_start_xx(value):
if str(value).startswith("xx"):
raise serializers.ValidationError("不能以xx开头")
class ProjectSerializses(serializers.ModelSerializer):
name = serializers.CharField(max_length=30, label="项目名称", help_text="项目名称",
validators=[validators.UniqueValidator(queryset=Projects.objects.all(),
message="name字段只能是唯一的"),is_start_xx],
error_messages={
"required":"name字段必传"})
class Meta:
# 必须指定model,指定要映射的模型类
model = Projects
# 1.fields和exclude不能同时存在
# 2.fields=("name","leader"),可以指定某一个或几个字段
fields = "__all__" # 指定所有
# exclude中的字段是既不输入也可以不输出
# exclude = ("create_time","update_time")
# extra_kwargs说明:
# 1.若是在序列化器类中定义了同名类属性则在extra_kwargs写的则无效,
# 2.若是没定义类属性,则满足覆盖添加原则
extra_kwargs = {
"leader": {
"max_length": 5,
}
}
# 单字段校验:校验方式是以validate_字段名称
def validate_name(self, name):
if str(name).endswith("xx"):
raise serializers.ValidationError("不能以xx结尾")
return name
# 多字段校验:直接使用validate,但是必须返回attrs
def validate(self, attrs):
name = attrs["name"]
leader = attrs["leader"]
if re.search(r"##",name) and re.search(r"##",leader):
raise serializers.ValidationError("name和leader中不能同时包含#")
return attrs
b. views.py文件
class ProjectsView(View):
def get(self,request):
"""
输出所有的项目信息
:param request:
:return:
"""
# 获取查询集—》传给序列化器,对于查询集对象,需要传many=True(对于单个模型类对象则不需要)
qs = Projects.objects.all()
ser = ProjectSerializses(instance=qs,many=True)
result = {
"code": "0", "message": "success", "data": ser.data}
return JsonResponse(result, safe=False)
def post(self, request):
# 1.获取请求参数
resquest_data = request.body
try:
# 2. 反序列化输入(将json字符串转化为python字典)
resquest_data = json.loads(resquest_data)
except:
result_data = {
"code": "1", "message": "请求参数有误"}
return JsonResponse(result_data, safe=False, status=200)
ser = ProjectSerializses(data=resquest_data)
try:
ser.is_valid(raise_exception=True)
except:
result_data = {
"code": "2", "message": "请求参数有误","data":ser.errors}
return JsonResponse(result_data, safe=False, status=200)
# 3. 进行数据库操作
# obj = Projects.objects.create(**resquest_data)
ser.save()
# 4.序列化输出(将模型类对象转换为json字符串)
# result = {"code": "0", "message": "success", "data": model_to_dict(obj)}
result = {
"code": "0", "message": "success", "data": ser.data}
return JsonResponse(result, safe=False)
class ProjectDetailView(View):
def get(self,request,pk):
ser = ProjectSerializses(instance=Projects.objects.get(id=pk))
result = {
"code": "0", "message": "success", "data": ser.data}
return JsonResponse(result, safe=False)
3.总结
1.序列化器可以用来进行参数校验
2.创建数据时:可以重写或者继承ModelSerializer中的create()方法(可选的)—>在view中使用序列化器中只传入data参数时,然后使用对象.save()方法可以进行数据的创建(用户post方法)
3.更新数据时:可以重写或者继承ModelSerializer中的update()方法(可选的)—>序列化器中传入instance和data参数时,然后使用对象.save()方法可以进行数据的更新(用于put和patch方法)
4.查询所有数据时:序列化器类中只需要传入查询集和many=True即可
5.查询单个数据时:序列化器类中只需要传入instance即可