drf基本使用(1)
Django Rest_Framework
核心思想: 缩短编写api接口的框架
Django REST framework是一个建立在Django基础之上的Web 应用开发框架,可以快速的开发REST API接口应用。在REST framework中,提供了序列化器Serialzier的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写工作。REST framework还提供了认证、权限、限流、过滤、分页、接口文档等功能支持。REST framework提供了一个API 的Web可视化界面来方便查看测试接口。
特点
-
提供了定义序列化器Serializer的方法,可以快速根据 Django ORM 或者其它库自动序列化/反序列化;
-
提供了丰富的类视图、Mixin扩展类,简化视图的编写;
-
丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要;
-
多种身份认证和权限认证方式的支持;[jwt]
-
内置了限流系统;
-
-
可扩展性,插件丰富
创建django项目
1 django-admin startproject demo1 2 3 python manage.py startapp student
1 INSTALLED_APPS = [ 2 ... 3 'rest_framework', 4 ]
接下来就可以使用DRF提供的功能进行api接口开发了。在项目中如果使用rest_framework框架实现API接口,主要有以下三个步骤:
-
将请求的数据(如JSON格式)转换为模型类对象
-
操作数据库
-
admin后台 管理系统的简单使用
首先在应用中创建模型对象
1 from django.db import models 2 3 4 class Student(models.Model): 5 # 模型字段 6 name = models.CharField(max_length=100,verbose_name="姓名", help_text="提示文本:账号不能为空!") 7 sex = models.BooleanField(default=True,verbose_name="性别") 8 age = models.IntegerField(verbose_name="年龄") 9 class_null = models.CharField(max_length=5,verbose_name="班级编号") 10 description = models.TextField(verbose_name="个性签名") 11 12 class Meta: 13 db_table = "tb_student" 14 verbose_name = "学生" # 创建admin中显示的表名字 15 verbose_name_plural = verbose_name # admin会默认在表名后面加s(复数),加上这句话就不会加s了
依次执行
1 python manage.py makemigrations 2 python manage.py miigrate 3 python mamage.py createsuperuser # 创建admin超级管理员用户
然后在我们应用中修改一下admin文件
from django.contrib import admin # Register your models here. from student import models class StudentAdmin(admin.ModelAdmin): list_display = ['id', 'name', 'sex', 'class_null'] # admin所要展示的字段 list_editable = ['name', 'sex'] # 可以在admin展示的时候进行修改 # 注册我们的表到admin中显示 admin.site.register(models.Student, StudentAdmin)

这里显示的是学生,是因为我们在models中最后添加的 两行, 我们注释掉最后两行在访问可以看到显示的是我们的表名
而且默认是以复数的形式显示,在表名后面给我们加了一个s

在admin中就可以操作我们的数据库,添加记录了
创建序列化器
首先配置好我们的项目后,就开始第一步了 modelserializer的详情使用
- 这里我们创建了一个student应用, 在下面创建一个serializers.py文件来创建我们的序列化器,名称随意
from rest_framework import serializers from student import models class StudentModelSerializer(serializers.ModelSerializer): class Meta: model = models.Student # 与student表对应 fields = '__all__' ''' model 指定该序列化器处理的字段从模型类student参考而成 fields 指定该序列化器包含模型类中的哪些字段 all指明包含所有字段 '''
- 编写视图
在student应用的views.py中创建视图StudentViewSet, 这是一个视图集合
1 from rest_framework.viewsets import ModelViewSet 2 from .models import Student 3 from .serializers import StudentModelSerializer 4 # Create your views here. 5 class StudentViewSet(ModelViewSet): 6 queryset = Student.objects.all() 7 serializer_class = StudentModelSerializer
serializer_class
- 定义路由
在student应用的urls.py中定义路由信息。
from . import views from rest_framework.routers import DefaultRouter # 路由列表 urlpatterns = [] router = DefaultRouter() # 可以处理视图的路由器,自动通过视图来生成增删改查的url路径 router.register('students', views.StudentViewSet) #students是生成的url前缀,名称随便写, 向路由器中注册视图集 urlpatterns += router.urls # 将路由器中的所以路由信息追到到django的路由列表中
最后把students子应用中的路由文件加载到总路由文件中.
from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path("stu/",include("students.urls")), ]
运行测试\

序列化器serializer
声明序列化器,所有的序列化器都要直接或者间接继承于Serializer,
其中,ModelSerializer是Serializer的子类, ModelSerializer在Serializer的基础上进行了代码的优化
作用:
1 序列化, 序列化器会把模型类对象转化成字典,经过response以后就变成了json字符串 2 反序列化,把客户端发送过来的数据,经过request后变成字典,序列化器可以把字典转成模型类对象 3 反序列化, 完成数据校验功能
定义Serializer序列化器
1. 序列化queryset类型的数据
Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Serializer。
这里我们在创建一个ser应用
首先,定义序列化器serializer.py
from rest_framework import serializers class StudentSerializer(serializers.Serializer): # 需要进行数据转换的字段, 没有指定的不会转换,也不会进行序列化 id = serializers.IntegerField() name = serializers.CharField() age = serializers.IntegerField() description = serializers.CharField() # serializers中的CharField就代表TextField的意思 ''' 1. 如果序列化器集成的是ModelSerializer,则需要声明调用的模型类信息 2. 验证提交的数据的代码 3. 编写添加和更新模型的代码 '''
编写视图
创建Serializer对象
from django.views import View from ser import models from ser.serializer import StudentSerializer from django.http import JsonResponse class StudentsView(View): def get(self, request): # 先查询出模型类对象 student = models.Student.objects.all() # 构造序列化器对象 serializer = StudentSerializer(instance=student, many=True) # 若这里的模型类对象是多条, 就要加 many=True print(serializer.data, type(serializer.data)) # 获取序列化后的数据 获取的是[OrderedDict]类型的数据,列表套字典 # 响应数据 return JsonResponse(serializer.data, safe=False, json_dumps_params={'ensure_ascii': False})
配置路由
from django.urls import path from ser import views urlpatterns = [ path('students/', views.StudentsView.as_view()), ]
然后我们访问 127.0.0.1:8000/ser/students/, 就看到了我们序列化出来的字段

2. 序列化模型类对象(单条数据)
- 不需要many=True
- serializer.data 获取的是一个字典
# 序列化模型类对象 class StudentsView(View): def get(self, request): # 先查询出模型类对象 student = models.Student.objects.get(pk=1) # 构造序列化器对象 serializer = StudentSerializer(instance=student) # 若这里的模型类对象是单条, 不需要加many=True print(serializer.data, type(serializer.data)) # 单条数据获取的是一个字典 # {'id': 1, 'name': '筱田柚子', 'age': 21, 'description': 'I praise the Lord, then break the law我赞美主 但我也打破规则'} # 响应数据 return JsonResponse(serializer.data, safe=False, json_dumps_params={'ensure_ascii': False})
反序列化功能
这里我们使用postman模拟一下提交post请求,记得先把csrf_token验证注册掉
首先我们先改写我们的序列化器, 给序列化器加一些验证功能
class StudentSerializer2(serializers.Serializer): ''' 序列化对应字段数据时,需要在序列化器中声明和模型类中对应字段相同名称的属性字段 字段中默认有一个 required=True的字段,规定用户提交的不能为空 ''' id = serializers.IntegerField(read_only=True) # 序列化阶段需要,反序列化时不需要校验 name = serializers.CharField(max_length=12) # 对用户提交过来的数据进行校验, 长度不能超过12位 sex = serializers.BooleanField() age = serializers.IntegerField(max_value=18, error_messages={'required': '也不能没有呀'}) class_null = serializers.CharField(allow_blank=True,allow_null=True) # 用户可以不填这个字段,但也要提交一个空字符串
# class_null = serializer.CharField(required=False) # 可以不提交这个字段
description = serializers.CharField(write_only=True) # 该字段序列化时不会展示出来,反序列化时必须提交进行校验 ''' # 共同点 write_only=True required=True(要求提交的数据必须包含该字段数据) # 不同点: write_only=True 该字段数据序列化阶段不会被提取出来,反序列化时,必须要传过来进行校验,required=True该字段数据序列化阶段也会被提取出来 '''
views中添加POST方法
from ser.serializer import StudentSerializer2 class StudentsView(View): def post(self, request): print(request.POST) # <QueryDict: {}> 并没有获取到数据 ''' 因为我们发送的application是 json类似的数据,所以django并不能帮我们解析 request.POST中获取不到数据 ''' # print(request.data) serializer = StudentSerializer2(data=request.POST) if serializer.is_valid(): # 用户提交的数据必须校验,全部没有问题返回True # 使用validated_data获取提交的数据 print('校验成功后的数据', serializer.validated_data) # 然后保存数据 (这里就不保存了) return JsonResponse(serializer.validated_data) # 返回数据 else: # 使用serializer.errors 可以获取到校验失败后的数据 print(serializer.errors) return JsonResponse({'error': '校验失败'}, status=400)

如果用户提交的是json类型的数据格式呢
rest_framework只的APIView帮我们处理好了,将用户提交的json类型的数据处理成字典类型
通过request.data就可以获取到了, 其实不管什么类型的数据,都可以通过request.data获取到
# 针对用户如果发送的是json类型的数据, APIView中帮我们进行了处理 from rest_framework.views import APIView from ser import models from django.http import JsonResponse from ser.serializer import StudentSerializer2 class StudentsView(APIView): def get(self, request): # 先查询出模型类对象 student = models.Student.objects.get(pk=1) # 构造序列化器对象 serializer = StudentSerializer(instance=student) # 若这里的模型类对象是单条, 不需要加many=True print(serializer.data, type(serializer.data)) # 单条数据获取的是一个字典 # {'id': 1, 'name': '筱田柚子', 'age': 21, 'description': 'I praise the Lord, then break the law我赞美主 但我也打破规则'} # 响应数据 return JsonResponse(serializer.data, safe=False, json_dumps_params={'ensure_ascii': False}) def post(self, request): ''' 因为我们发送的application是 json类似的数据,所以django并不能帮我们解析 request.POST中获取不到数据 , APIView中将json类型的数据给我们处理好了, 使用request.data就可以拿取到 ''' print(request.data) # {'name': '加藤娜娜', 'age': 17} serializer = StudentSerializer2(data=request.data) if serializer.is_valid(): # 用户提交的数据必须校验,全部没有问题返回True # 使用validated_data获取提交的数据 print('校验成功后的数据', serializer.validated_data) # 然后保存数据 (这里就不保存了) return JsonResponse(serializer.validated_data) # 返回数据 else: # 使用serializer.errors 可以获取到校验失败后的数据 print(serializer.errors) return JsonResponse({'error': '校验失败'}, status=400)
再次提交可以看到我们提交成功了,

反序列化的校验功能
首先我们在我们的序列化器中对字段进行了校验, 如果用户的年龄大于18岁就会报错,然后通过serializer.error就可以获取到了




相关参数
定义好Serializer类后,就可以创建Serializer对象了。
Serializer(instance=None, data=empty, **kwarg)
说明:
1)用于序列化时,将模型类对象传入instance参数
2)用于反序列化时,将要被反序列化的数据传入data参数
3)除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如
serializer = AccountSerializer(account, context={'request': request})
通过context参数附加的数据,可以通过Serializer对象的context属性获取。
-
使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以。
-
序列化器无法直接接收数据,需要我们在视图中创建序列化器对象时把使用的数据传递过来。
-
序列化器的字段声明类似于我们前面使用过的表单系统。
-
开发restful api时,序列化器会帮我们把模型数据转换成字典.
-
drf提供的视图会帮我们把字典转换成json,或者把客户端发送过来的数据转换字典.
-
常用字段类型:
| 字段 | 字段构造方式 |
|---|---|
| BooleanField | BooleanField() |
| NullBooleanField | NullBooleanField() |
| CharField | CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) |
| EmailField | EmailField(max_length=None, min_length=None, allow_blank=False) |
| RegexField | RegexField(regex, max_length=None, min_length=None, allow_blank=False) |
| SlugField | SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+ |
| URLField | URLField(max_length=200, min_length=None, allow_blank=False) |
| UUIDField | UUIDField(format='hex_verbose') format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 微软时间戳,通过微秒生成一个随机字符串 |
| IPAddressField | IPAddressField(protocol='both', unpack_ipv4=False, **options) |
| IntegerField | IntegerField(max_value=None, min_value=None) |
| FloatField | FloatField(max_value=None, min_value=None) |
| DecimalField | DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置 |
| DateTimeField | DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None) |
| DateField | DateField(format=api_settings.DATE_FORMAT, input_formats=None) |
| TimeField | TimeField(format=api_settings.TIME_FORMAT, input_formats=None) |
| DurationField | DurationField() |
| ChoiceField | ChoiceField(choices) choices与Django的用法相同 |
| MultipleChoiceField | MultipleChoiceField(choices) |
| FileField | FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
| ImageField | ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
| ListField | ListField(child=, min_length=None, max_length=None) |
| DictField | DictField(child=) |
选项参数:
| 参数名称 | 作用 |
|---|---|
| max_length | 最大长度 |
| min_length | 最小长度 |
| allow_blank | 是否允许为空 |
| trim_whitespace | 是否截断空白字符 |
| max_value | 最大值 |
| min_value | 最小值 |
通用参数:
| 参数名称 | 说明 |
|---|---|
| read_only | 表明该字段仅用于序列化输出,默认False |
| write_only | 表明该字段仅用于反序列化输入,默认False |
| required | 表明该字段在反序列化时必须输入,默认True |
| default | 反序列化时使用的默认值 |
| allow_null | 表明该字段是否允许传入None,默认False |
| validators | 该字段使用的验证器 |
| error_messages | 包含错误编号与错误信息的字典 |
| label | 用于HTML展示API页面时,显示的字段名称 |
| help_text | 用于HTML展示API页面时,显示的字段帮助提示信息 |
本文来自博客园,作者:长情不羁的五年,转载请注明原文链接:https://www.cnblogs.com/grlend/articles/14141278.html

浙公网安备 33010602011771号