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]

  • 内置了限流系统;

  • 直观的 API web 界面;

  • 可扩展性,插件丰富

 创建django项目 

 

1 django-admin startproject demo1 
2 
3 python manage.py startapp student

 

settings.pyINSTALLED_APPS中添加'rest_framework'。

1 INSTALLED_APPS = [
2     ...
3     'rest_framework',
4 ]

 

接下来就可以使用DRF提供的功能进行api接口开发了。在项目中如果使用rest_framework框架实现API接口,主要有以下三个步骤:

  • 将请求的数据(如JSON格式)转换为模型类对象

  • 操作数据库

  • 将模型类对象转换为响应的数据(如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

 

queryset 指明该视图集在查询数据时使用的查询集

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不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。

编写视图  

创建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. 序列化模型类对象(单条数据)

  1.  不需要many=True 
  2. 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的构造方法为:

Serializer(instance=None, data=empty, **kwarg)

说明:

1)用于序列化时,将模型类对象传入instance参数

2)用于反序列化时,将要被反序列化的数据传入data参数

3)除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如

serializer = AccountSerializer(account, context={'request': request})

通过context参数附加的数据,可以通过Serializer对象的context属性获取。

 

  1. 使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以。

  2. 序列化器无法直接接收数据,需要我们在视图中创建序列化器对象时把使用的数据传递过来。

  3. 序列化器的字段声明类似于我们前面使用过的表单系统。

  4. 开发restful api时,序列化器会帮我们把模型数据转换成字典.

  5. drf提供的视图会帮我们把字典转换成json,或者把客户端发送过来的数据转换字典.

  6.  

 

 

 

常用字段类型

字段字段构造方式
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页面时,显示的字段帮助提示信息

 

posted @ 2020-12-15 22:00  死里学  阅读(286)  评论(0)    收藏  举报