python开发框架——Django基础知识(十一)

python开发框架——Django基础知识(十一),第1张


  hello!我是小J,每天一个小知识,一起学python,让技术无限发散。

DRF和Web
  • 1. web应用模式
    • 1.1 前后端不分离
    • 1.2 前后端分离
  • 2. 使用Django开发REST接口
    • 2.1 什么是REST
    • 2.2 REST的规范使用
      • 2.2.1 查询数据
      • 2.2.2 添加数据
      • 2.2.3 删除、修改数据
  • 3. DRF介绍和安装
    • 3.1 DRF介绍
    • 3.2 DRF特点介绍
    • 3.3 DRF使用
    • 3.4 序列化反序列化器
      • 3.4.1 序列化
      • 3.4.2 反序列化
    • 3.5 DRF视图
      • 3.5.1 两个基本类视图
      • 3.5.2 五个扩展类
        • 3.5.2.1 ListModelMixin列表视图扩展类
        • 3.5.2.2 CreateModelMixin创建视图扩展类
        • 3.5.2.3 RetrieveModelMixin详情视图扩展类
        • 3.5.2.4 UpdateModelMixin更新视图扩展类
        • 3.5.2.5 DestroyModelMixin删除视图扩展类
      • 3.5.3 扩展类视图的子类
        • 3.5.3.1 CreateAPIView
        • 3.5.3.2 ListAPIView
        • 3.5.3.3 ListCreateAPIView
        • 3.5.3.3 RetrieveAPIView
        • 3.5.3.4 UpdateAPIVIew
        • 3.5.3.5 DestoryAPIView
      • 3.5.4 视图集
  • 结束语

1. web应用模式 1.1 前后端不分离


  前后端不分离的应用模式中,前端代码和后端代码是在一块的,需要一个服务器就行,前端页面看到的效果是由后端控制,经后端渲染模板或重定向,后端控制着前端的展示,前后端的耦合度非常高。这种应用模式比较适合纯网页应用。但是当后端对接App时,App可能不需要后端返回一个html页面,而只需要接收数据本身,这样原本后端返回网页的接口不再适用于前端的App应用,为了实现对接App还需要再开发一套接口。

1.2 前后端分离


  在前后端分离的应用模式中,前端代码和后端代码时分开的,需要两个服务器,后端仅仅返回前端所需要的数据,不再渲染HTML页面,也不再控制前端的效果。至于前端用户能看到什么效果,均是由后端请求的数据加载到前端中,由前端觉得,网页有网页的处理方式,App有App的处理方式。但是无论哪种前端,所需要的数据基本相同,后端仅仅需要开发一套逻辑对外提供数据即可。在前后端分离的应用模式中,前端和后端的耦合度相对较低,通常后端开发的每个视图都称为一个接口(API),前端通过访问接口来对数据进行增删改查。

2. 使用Django开发REST接口

在了解什么是REST之前,我们需要了解一下API和Web更有助于我们了解REST,因为REST是基于Web为平台的一种架构风格,在开发API时需要遵循的一种风格,当然也存在其他规则可用。

2.1 什么是REST
  • API 英文为Application Programming Interface,中文为应用程序编程接口,是一些预先定义的函数,目的是为了提供应用程序与开发人员基于某些软件或硬件可以访问一组例程的能力,而无需理解内部工作机制的细节或无需访问源码。就像平时大家可以将其他软件里的内容分享到微信朋友圈,这些软件就和微信的API进行了交互。

  • Web是分布式信息系统为超文本文件和其他对象提供访问的入口,资源(对象)是Web架构的关键点,存在3个 *** 作:

    所以REST,英文Resource Representational State Transfer的缩写,中文资源在网络中以某种表现形式进行状态转移就是选择通过http协议和uri,利用client/server model对资源进行增删改查 *** 作。REST描述的是在网络中client和server的一种交互形式;REST本身不实用,实用的是如何设计 RESTful API(REST风格的网络接口)。对于资源的具体 *** 作类型,由HTTP动词表示。常用的HTTP动词有下面五个(括号里是对应的SQL命令):

2.2 REST的规范使用 2.2.1 查询数据

在视图函数中编写类来查询数据库,查询数据是把数据构造为字典用来响应给浏览器(前端)

# 用类的方式来查询数据库
from .models import PeopleInfo,BookInfo
class BookInfoView(View):
    """
    列表数据
    查询所有的图书数据
    """
    def get(self,request):
        # books = BookInfo.objects.all()
        books = BookInfo.objects.filter(is_delete=False)
        print(books)
        book_list = []
        for book in books:
            book_dict = {
                'id':book.id,
                'name':book.name,
                'pub_date':book.pub_date,
                'readcount':book.readcount,
                'commentcount':book.commentcount,
                'image':book.image.url if book.image else ''
            }
            book_list.append(book_dict)
        print(book_list)
        return JsonResponse(book_list,safe=False)

路由:path('book/',views.BookInfoView.as_view()),

结果:

2.2.2 添加数据

使用post方法添加数据,获取数据,把数据进行转换为字典,构造响应的数据给浏览器(前端)

# 用类的方式来查询数据库
class BookInfoView(View):
    """
    列表数据
    查询所有的图书数据
    """
    def get(self,request):
        # books = BookInfo.objects.all()
        books = BookInfo.objects.filter(is_delete=False)
        print(books)
        book_list = []
        for book in books:
            book_dict = {
                'id':book.id,
                'name':book.name,
                'pub_date':book.pub_date,
                'readcount':book.readcount,
                'commentcount':book.commentcount,
                'image':book.image.url if book.image else ''
            }
            book_list.append(book_dict)
        print(book_list)
        return JsonResponse(book_list,safe=False)

    def post(self,request):
        """
        添加数据
        :param request:
        :return:
        """
        # 获取到修改的数据
        # print(request)
        json_bytes = request.body
        # 转换为字符串
        json_str = json_bytes.decode()
        # 转换为字典
        import json
        book_dict = json.loads(json_str)
        print(book_dict)
        # 保存数据
        book = BookInfo.objects.create(
            name = book_dict['name'],
            pub_date = book_dict['pub_date']
        )
        book_dict = {
            'id': book.id,
            'name': book.name,
            'pub_date': book.pub_date,
            'readcount': book.readcount,
            'commentcount': book.commentcount,
            'image': book.image.url if book.image else ''
        }

        return JsonResponse(book_dict)

结果:

2.2.3 删除、修改数据

修改数据流程:

  • ①获取要修改的数据,转换为字典
  • ②查询一下要修改的数据是否存在
  • ③存在数据就修改,并保存
  • ④响应

删除数据流程:获取删除的数据,去和数据库进行对比,如果有这个数据就删除,把删除的结果返回给浏览器

# 修改指定的数据
class BookDetailView(View):
    # 获取指定的数据
    def get(self,request,pk):
        # 查询这个ID对应的数据是否存在
        try:
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            return JsonResponse({'message':'error:%s'%e},status=404)
        book_dict = {
            'id': book.id,
            'name': book.name,
            'pub_date': book.pub_date,
            'readcount': book.readcount,
            'commentcount': book.commentcount,
            'image': book.image.url if book.image else ' '
        }

        return JsonResponse(book_dict)

    # 删除数据
    def delete(self,request,pk):
        try:
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            return JsonResponse({'message':'error:%s'%e},status=404)

        book.delete()
        return JsonResponse({'message':'delete success'},status=204)

    def put(self,request,pk):
        """
         修改指定的某个图书数据
        """
        try:
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            return JsonResponse({'message':'error:%s'%e},status=404)
        # 获取传过来的数据
        json_bytes = request.body
        print(json_bytes)
        # 转换为字符串
        json_str = json_bytes.decode()
        # 转换为字典
        import json
        book_dict = json.loads(json_str)
        print(book_dict)
        # 保存
        book.name = book_dict['name']
        book.pub_date = book_dict['pub_date']
        # 返回数据,构造数据
        json_dict = {
            'id':book.id,
            'name':book.name,
            'pub_date':book.pub_date,
        }


        return JsonResponse(data=json_dict,status=200)

路由:path('book//',views.BookDetailView.as_view()),

结果:
使用put修改数据

使用delete删除数据

3. DRF介绍和安装 3.1 DRF介绍

  DRF框架全称:Django-REST-Framework,是一种后端框架,是基于RESTful风格的框架,该框架主要做的是前后的分离时接口的规范的编写。

3.2 DRF特点介绍
  • 提供了序列化器,自动进行序列化和反序列化
  • 提供了丰富的扩展类,简化了代码的编写
  • 可扩展性强
  • 丰富的定制层级
  • 内置了身份认证和权限控制以及限流
3.3 DRF使用
  • 安装
pip install djangorestframework
  • 注册应用
    在setting中的的INSTALLED_APP中添加rest_framework
# 注册子应用的地方
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'books.apps.BooksConfig',
    # 添加
    'rest_framework',
]

  • DRF的简单使用
    在books文件夹下新建一个serializer.py文件,在文件里创建一个简单的序列化模型类
from rest_framework import serializers
from books.models import BookInfo

# 序列化模型类
class BookInfoSerializer(serializers.ModelSerializer):
    """
    图书序列器
    """
    class Meta:
        # 指定序列化的模型类
        model = BookInfo
        # 指定序列化器包含哪些字段
        fields = '__all__'  # __all__序列化模型类所有的字段

在views.py文件中新建一个视图类用于调用之前创建的序列化模型类

from rest_framework.viewsets import ModelViewSet
from .serializer import BookInfoSerializer
class BookInfoview(ModelViewSet):
    # ModelViewSet  自己实现了不同的请求方法
    # 查询模型类的数据   查询集
    queryset = BookInfo.objects.all()
    # 指定使用的序列化器的
    serializer_class = BookInfoSerializer

在urls.py文件中去创建路由

from rest_framework.routers import DefaultRouter
router = DefaultRouter()
# 向默认的路由器注册视图
router.register(r'books',views.BookInfoview)

# 将这个路由器的信息追加到Django的路由列表中
urlpatterns += router.urls

结果:

点击页面中的地址:http://127.0.0.1:8000/books/

通过http://127.0.0.1:8000/books/1/

3.4 序列化反序列化器
  • 序列化:就是将数据从数据库(模型类)中查询出来,构造成字典数据,然后再返回的这个过程,结果是json。
  • 反序列化:将json的字符串类型转换为Django模型类对象的数据
3.4.1 序列化
  • 模型类序列化器
    • 依照模型类,自动生成序列化字段的序列化器,并且根据模型类生成验证函数和实现了create()和update()方法
      • 使用
        • 继承自serializer.Modelserializer
        • 通过class Meta指定元数据
          • models=参照的模型类名
          • fields=(需要为模型类中的那些字段生成),all表示所有字段
          • exclude=(不需要为模型类中的那些字段生成)
          • extra_kwargs={字段名:选项参数}可以为生成的序列化器字段增加约束
          • depth=嵌套返回的层级
          • read_only_fields=(指明只参加序列化返回的字段)
          • write_only_fields=(指明只参加反序列化验证的字段)

序列化流程

  • 1.准备序列化的模型类对象
  • 2.把模型类对象添加到指定的序列化器中
  • 3,获取数据转换后的数据

序列化器的作用:

  • 对数据进行转换

  • 进行数据的检验

  • 可用字段

  • 选项参数

  • 通用参数

  • 定义序列化模型类

from rest_framework import serializers
from books.models import BookInfo

class BookInfoSerializers(serializers.Serializer):
    # 接收到数据然后进行转换  IntegerField() 这个属性方法
    # read_only指定这个字段做序列化输出的
    id = serializers.IntegerField(label='ID',read_only=True)
    name = serializers.CharField(label='名称',max_length=50,read_only=True)
    pub_date = serializers.DateField(label='日期',required=False)
    readcount = serializers.IntegerField(label='阅读量',required=False)
    commentcount = serializers.IntegerField(label='评论量',required=False)
    is_delete = serializers.BooleanField(label='删除',required=False)
    image = serializers.ImageField(label='图片',required=False)

在终端中打开shell演示工具python manage.py shell

>>> from books.serializer import BookInfoSerializers
>>> from books.models import BookInfo
>>> book = BookInfo.objects.get(id=2)
>>> book
<BookInfo: 天龙八部>

>>> ser = BookInfoSerializers(book)
>>> ser.data
{'id': 2, 'name': '天龙八部', 'pub_date': '1986-07-24', 'readcount': 36, 
'commentcount': 40, 'is_delete': False, 'image': None}

>>> books_qs = BookInfo.objects.all()
>>> ser = BookInfoSerializers(books_qs,many=True)
>>> ser.data
[OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pub_date', '1980-05-01
'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('imag
e', None)]), OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '
1986-07-24'), ('readcount', 36), ('commentcount', 40), ('is_delete', Fals
e), ('image', None)]), OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pu
b_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_del
ete', False), ('image', None)]), OrderedDict([('id', 4), ('name', '雪山飞
狐'), ('pub_date', '1987-11-11'), ('readcount', 58), ('commentcount', 24)
, ('is_delete', False), ('image', None)]), OrderedDict([('id', 10), ('nam
e', 'hello'), ('pub_date', '2022-05-11'), ('readcount', 0), ('commentcoun
t', 20), ('is_delete', True), ('image', None)]), OrderedDict([('id', 11),
 ('name', 'python'), ('pub_date', '2022-05-10'), ('readcount', 20), ('com
mentcount', 0), ('is_delete', False), ('image', '/1.jpg')]), OrderedDict(
[('id', 27), ('name', 'python'), ('pub_date', '2022-05-14'), ('readcount'
, 0), ('commentcount', 0), ('is_delete', False), ('image', None)])]      
>>>
  • 存在外键的模型类进行序列化输出
# 存在外键的模型类 怎么做序列化
class PeopleInfoSerializer(serializers.ModelSerializer):

    id = serializers.IntegerField(label='ID',read_only=True)
    name = serializers.CharField(label='名称',max_length=40)
    gender = serializers.IntegerField(label='性别',required=False)
    description = serializers.CharField(label='描述',required=False)
    is_delete = serializers.BooleanField(label='删除',required=False)

    book = serializers.StringRelatedField(label='图书')
    class Meta:
        model = PeopleInfo
        fields = '__all__'

结果:

>>> from books.serializer import PeopleInfoSerializer
>>> from books.models import PeopleInfo
>>> people = PeopleInfo.objects.get(id=2)
>>> ser = PeopleInfoSerializer(people)
>>> ser.data
{'id': 2, 'name': '黄蓉', 'gender': 0, 'description': '打狗棍法', 'is_del
ete': False, 'book': '射雕英雄传'}
>>> peoples = PeopleInfo.objects.all()
>>> ser = PeopleInfoSerializer(peoples,many=True)
>>> ser.data
[OrderedDict([('id', 1), ('name', '郭靖'), ('gender', 1), ('description',
 '降龙十八掌'), ('is_delete', False), ('book', '射雕英雄传')]), OrderedDi
ct([('id', 2), ('name', '黄蓉'), ('gender', 0), ('description', '打狗棍法
'), ('is_delete', False), ('book', '射雕英雄传')]), OrderedDict([('id', 3
), ('name', '黄药师'), ('gender', 1), ('description', 'd指神通'), ('is_d
elete', False), ('book', '射雕英雄传')]), OrderedDict([('id', 4), ('name'
, '欧阳锋'), ('gender', 1), ('description', '蛤蟆功'), ('is_delete', Fals
e), ('book', '射雕英雄传')]), OrderedDict([('id', 5), ('name', '梅超风'),
 ('gender', 0), ('description', '九阴白骨爪'), ('is_delete', False), ('bo
ok', '射雕英雄传')]), OrderedDict([('id', 6), ('name', '乔峰'), ('gender'
, 1), ('description', '降龙十八掌'), ('is_delete', False), ('book', '天龙
八部')]), OrderedDict([('id', 7), ('name', '段誉'), ('gender', 1), ('desc
ription', '六脉神剑'), ('is_delete', False), ('book', '天龙八部')]), Orde
redDict([('id', 8), ('name', '虚竹'), ('gender', 1), ('description', '天 
山六阳掌'), ('is_delete', False), ('book', '天龙八部')]), OrderedDict([('
id', 9), ('name', '王语嫣'), ('gender', 0), ('description', '神仙姐姐'), 
('is_delete', False), ('book', '天龙八部')]), OrderedDict([('id', 10), ('
name', '令狐冲'), ('gender', 1), ('description', '独孤九剑'), ('is_delete
', False), ('book', '笑傲江湖')]), OrderedDict([('id', 11), ('name', '任 
盈盈'), ('gender', 0), ('description', 'd琴'), ('is_delete', False), ('b
ook', '笑傲江湖')]), OrderedDict([('id', 12), ('name', '岳不群'), ('gende
r', 1), ('description', '华山剑法'), ('is_delete', False), ('book', '笑傲
江湖')]), OrderedDict([('id', 13), ('name', '东方不败'), ('gender', 0), (
'description', '葵花宝典'), ('is_delete', False), ('book', '笑傲江湖')]),
 OrderedDict([('id', 14), ('name', '胡斐'), ('gender', 1), ('description'
, '胡家刀法'), ('is_delete', False), ('book', '雪山飞狐')]), OrderedDict(
[('id', 15), ('name', '苗若兰'), ('gender', 0), ('description', '黄衣'), 
('is_delete', False), ('book', '雪山飞狐')]), OrderedDict([('id', 16), ('
name', '程灵素'), ('gender', 0), ('description', '医术'), ('is_delete', F
alse), ('book', '雪山飞狐')]), OrderedDict([('id', 17), ('name', '袁紫衣'
), ('gender', 0), ('description', '六合拳'), ('is_delete', False), ('book
', '雪山飞狐')])]
>>>

  • 把关联的数据全部通过外键的方式查询出来进行序列化显示
    book = serializers.StringRelatedField(label='图书')更换为book = BookInfoSerializers()就可以实现
class PeopleInfoSerializer(serializers.ModelSerializer):

    id = serializers.IntegerField(label='ID',read_only=True)
    name = serializers.CharField(label='名称',max_length=40)
    gender = serializers.IntegerField(label='性别',required=False)
    description = serializers.CharField(label='描述',required=False)
    is_delete = serializers.BooleanField(label='删除',required=False)

    # book = serializers.StringRelatedField(label='图书')
    book = BookInfoSerializers()
    class Meta:
        model = PeopleInfo
        fields = '__all__'

结果:

>>> from books.serializer import PeopleInfoSerializer,BookInfoSerializers
>>> from books.models import PeopleInfo                                   
>>> people = PeopleInfo.objects.get(id=2)
>>> people
<PeopleInfo: 黄蓉>
>>> ser = PeopleInfoSerializer(people) 
>>> ser.data
{'id': 2, 'name': '黄蓉', 'gender': 0, 'description': '打狗棍法', 'is_delete': False, 'book': OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pu
b_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)])}
>>> peoples = PeopleInfo.objects.all()    
>>> ser = PeopleInfoSerializer(peoples,many=True)
>>> ser.data                                      
[OrderedDict([('id', 1), ('name', '郭靖'), ('gender', 1), ('description', '降龙十八掌'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('
name', '射雕英雄传'), ('pub_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict
([('id', 2), ('name', '黄蓉'), ('gender', 0), ('description', '打狗棍法'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('name', '射雕英
雄传'), ('pub_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 3), (
'name', '黄药师'), ('gender', 1), ('description', 'd指神通'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pu
b_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 4), ('name', '欧 
阳锋'), ('gender', 1), ('description', '蛤蟆功'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pub_date', '198
0-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 5), ('name', '梅超风'), ('gend
er', 0), ('description', '九阴白骨爪'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pub_date', '1980-05-01'),
 ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 6), ('name', '乔峰'), ('gender', 1), ('d
escription', '降龙十八掌'), ('is_delete', False), ('book', OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '1986-07-24'), ('readcount',
 36), ('commentcount', 40), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 7), ('name', '段誉'), ('gender', 1), ('description', '
六脉神剑'), ('is_delete', False), ('book', OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '1986-07-24'), ('readcount', 36), ('commentc
ount', 40), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 8), ('name', '虚竹'), ('gender', 1), ('description', '天山六阳掌'), ('
is_delete', False), ('book', OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '1986-07-24'), ('readcount', 36), ('commentcount', 40), ('
is_delete', False), ('image', None)]))]), OrderedDict([('id', 9), ('name', '王语嫣'), ('gender', 0), ('description', '神仙姐姐'), ('is_delete', Fa
lse), ('book', OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '1986-07-24'), ('readcount', 36), ('commentcount', 40), ('is_delete', Fa
lse), ('image', None)]))]), OrderedDict([('id', 10), ('name', '令狐冲'), ('gender', 1), ('description', '独孤九剑'), ('is_delete', False), ('book'
, OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_delete', False), ('image
', None)]))]), OrderedDict([('id', 11), ('name', '任盈盈'), ('gender', 0), ('description', 'd琴'), ('is_delete', False), ('book', OrderedDict([('
id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_delete', False), ('image', None)]))]), Or
deredDict([('id', 12), ('name', '岳不群'), ('gender', 1), ('description', '华山剑法'), ('is_delete', False), ('book', OrderedDict([('id', 3), ('na
me', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_delete', False), ('image', None)]))]), OrderedDict([('
id', 13), ('name', '东方不败'), ('gender', 0), ('description', '葵花宝典'), ('is_delete', False), ('book', OrderedDict([('id', 3), ('name', '笑傲 
江湖'), ('pub_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 14), 
('name', '胡斐'), ('gender', 1), ('description', '胡家刀法'), ('is_delete', False), ('book', OrderedDict([('id', 4), ('name', '雪山飞狐'), ('pub_d
ate', '1987-11-11'), ('readcount', 58), ('commentcount', 24), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 15), ('name', '苗若 
兰'), ('gender', 0), ('description', '黄衣'), ('is_delete', False), ('book', OrderedDict([('id', 4), ('name', '雪山飞狐'), ('pub_date', '1987-11-1
1'), ('readcount', 58), ('commentcount', 24), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 16), ('name', '程灵素'), ('gender', 
0), ('description', '医术'), ('is_delete', False), ('book', OrderedDict([('id', 4), ('name', '雪山飞狐'), ('pub_date', '1987-11-11'), ('readcount'
, 58), ('commentcount', 24), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 17), ('name', '袁紫衣'), ('gender', 0), ('description
', '六合拳'), ('is_delete', False), ('book', OrderedDict([('id', 4), ('name', '雪山飞狐'), ('pub_date', '1987-11-11'), ('readcount', 58), ('commen
tcount', 24), ('is_delete', False), ('image', None)]))])]
>>>
3.4.2 反序列化

反序列化流程

  • 1.准备要输入的数据 (json类型)
  • 2.把输入的数据添加到序列化器里面
  • 3.调用验证的方法去验证一下序列化器中转换的数据是否成功
  • 4.获取反序列化的数据 模型类对象数据
>>> from books.serializer import BookInfoSerializers
>>> book = {'name':'python'}
>>> ser.is_valid()
True
>>> ser.validated_data
OrderedDict([('name', 'python')])
>>>
3.5 DRF视图 3.5.1 两个基本类视图
  • ①APIView
    • 继承自Django的view类
    • 提供的额外功能
    • 身份认证
      • authentication_classes:身份认证类
  • 权限检查
    • permission_classes;权限检查类
  • 流量控制
    • throttle_classes:流量控制类
from rest_framework.views import APIView
from rest_framework import request, status
from rest_framework.response import Response
from .serializer import BookInfoSerializer
class BookListAPIView(APIView):
    """
    列表视图  instance 做序列化输出的时候 data 做反序列化的时候
    """
    def get(self,request):
        # 查询所有图书
        qs = BookInfo.objects.all()
        ser = BookInfoSerializer(instance=qs,many=True)
        return Response(ser.data)

    def post(self,request):
        # 获取传入的数据
        data = request.data
        print(data)
        ser = BookInfoSerializer(data=data)
        ser.is_valid(raise_exception=True)
        ser.save()
        return Response(ser.data,status=status.HTTP_201_CREATED)     

结果:
get查看数据表

post添加数据

put修改数据

class BookDetailAPIView(APIView):
    def put(self,request,pk):
        try:
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            return Response(e,status=status.HTTP_404_NOT_FOUND)
        ser = BookInfoSerializer(instance=book,data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        return Response(ser.data,status=status.HTTP_201_CREATED)

结果:

删除数据:

class BookDetailAPIView(APIView):
    def put(self,request,pk):
        """
        查询指定的pk 进行修改
        :param request: 
        :param pk: 
        :return: 
        """
        try:
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            return Response(e,status=status.HTTP_404_NOT_FOUND)
        ser = BookInfoSerializer(instance=book,data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        return Response(ser.data,status=status.HTTP_201_CREATED)

    def delete(self,request,pk):
        """
        查询指定的pk 进行删除
        :param request:
        :param pk:
        :return:
        """
        try:
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            return JsonResponse(data={"magess":"没有这个数据"},status=status.HTTP_404_NOT_FOUND)
        # 如果有这个数据就删除
        book.delete()
        return JsonResponse(data={'magess':'delete success'},status=status.HTTP_204_NO_CONTENT)

结果:

  • ②GenericAPIView

    • 继承自APIView
    • 提供的额外功能
      • 四个属性

        • serialzer_class(指定使用的序列化器)
        • query_set(指定使用的查询集)
        • pagination_class(分页控制类)
        • filter_backends(指明过滤控制后端)
      • 四个方法

        • get_serializer(获取当前的序列化器):内部调用了get_serializer_class获取类属性指定的序列化器,然后实例化生成序列化器
        • get_object(获取更新的数据对象):内部调用了get_queryset获取指定的查询集
        • get_queryset(获取指定的查询集)
        • get_serializer_class(获取当前的序列化器类)
  • get查询数据

# GenericAPIView 继承自APIView 增加了对列表视图和详情视图可以使用的方法,进行了通用支持
from rest_framework.generics import GenericAPIView
"""
queryset = None  查询集  列表视图的查询集  接收查询集的数据
serializer_class = None  # 视图使用的序列化器
lookup_field = 'pk'  查询单个数据对象使用的条件默认是”pk“
lookup_url_kwarg = None   pk=books_id
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS  过滤控制后端的数据显示
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS  分页控制类
"""
class BookListGenericAPIView(GenericAPIView):
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer

    def get(self,request):
        # 获取查询集
        qs = self.get_queryset()
        # 返回序列化器对象
        ser = self.get_serializer(qs,many=True)
        return Response(ser.data)

路由:path('books/',views.BookListGenericAPIView.as_view()),

结果:

  • post添加数据
 def post(self,request):
      # 获取传入的数据
      data = request.data
      print(data)
      ser = BookInfoSerializer(data=data)
      ser.is_valid(raise_exception=True)
      ser.save()
      return Response(ser.data,status=status.HTTP_201_CREATED)

结果:

  • put修改数据
    路由:path('books//',views.BookDetailGenericAPIView.as_view()),
class BookDetailGenericAPIView(GenericAPIView):
    def put(self,request,pk):
        # 调用get_queryset()  去实现查询
        book = self.get_queryset()
        #
        ser = self.get_serializer(book,request.data)
        # 验证数据
        ser.is_valid(raise_exception=True)
        # 保存数据
        ser.save()
        return Response(ser.data)

结果:

  • delete删除数据
class BookDetailGenericAPIView(GenericAPIView):
    def put(self,request,pk):
        # 调用get_queryset()  去实现查询
        book = self.get_queryset()
        #
        ser = self.get_serializer(book,request.data)
        # 验证数据
        ser.is_valid(raise_exception=True)
        # 保存数据
        ser.save()
        return Response(ser.data)

    def delete(self,request,pk):
        """
        查询指定的pk 进行删除
        :param request:
        :param pk:
        :return:
        """
        try:
            # 查询指定的pk
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            return Response(status=status.HTTP_404_NOT_FOUND,data={"magess":"数据不存在"})

        # 如果有这个数据就删除
        book.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

结果:

3.5.2 五个扩展类 3.5.2.1 ListModelMixin列表视图扩展类

路由:path('books/',views.BookListModelMixin.as_view())

# ListModelMixin 列表视图扩展类
from rest_framework.mixins import ListModelMixin

class BookListModelMixin(ListModelMixin,GenericAPIView):
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer
    def get(self,request):
        return self.list(request)

结果:

3.5.2.2 CreateModelMixin创建视图扩展类
  • 路由:path('books/',views.BookCreateModelMixin.as_view()),
# CreateModelMixin 创建视图扩展类 添加视图扩展类
from rest_framework.mixins import CreateModelMixin

class BookListModelMixin(CreateModelMixin,ListModelMixin,GenericAPIView):
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器
    serializer_class = BookInfoSerializer
    def get(self,request):
        return self.list(request)
    def post(self,request):
        return self.create(request)

post添加数据结果:

get获取数据结果:

3.5.2.3 RetrieveModelMixin详情视图扩展类

路由:path('books/',views.BookRetrieveModelMixin.as_view()),

# RetrieveModelMixin 详情视图扩展类 用于单个数据的查询 这个必须在路由里面传入参数
from rest_framework.mixins import RetrieveModelMixin

class BookRetrieveModelMixin(RetrieveModelMixin,CreateModelMixin,ListModelMixin,GenericAPIView):
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer
    def get(self,request,pk):
        return self.list(request)

结果:

3.5.2.4 UpdateModelMixin更新视图扩展类

路由:path('books//',views.BookUpdateModelMixin.as_view()),

# UpdateModelMixin 更新视图扩展类
from rest_framework.mixins import UpdateModelMixin

class BookUpdateModelMixin(UpdateModelMixin,RetrieveModelMixin,CreateModelMixin,ListModelMixin,GenericAPIView):
    """
    更新视图
    """
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer
    def get(self,request,pk):
        return self.retrieve(request,pk)

    def put(self,request,pk):
        return self.update(request,pk)

get获取数据结果:

put修改数据结果:

3.5.2.5 DestroyModelMixin删除视图扩展类

路由:path('books//', views.BookDestroyModelMixin.as_view()),

# DestroyModelMixin 删除视图扩展类
from rest_framework.mixins import DestroyModelMixin

class BookDestroyModelMixin(DestroyModelMixin,UpdateModelMixin,RetrieveModelMixin,CreateModelMixin,ListModelMixin,GenericAPIView):
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer

    def get(self, request, pk):
        return self.retrieve(request, pk)

    def put(self, request, pk):
        return self.update(request, pk)

    def delete(self, request, pk):
        return self.destroy(request, pk)

结果:

3.5.3 扩展类视图的子类

继承扩展类中的一i邪恶方法和基类中的一些方法,也不能单独继承使用必须继承一个基类。

3.5.3.1 CreateAPIView

保存单个数据,实现了post方法,路由:path('books/',views.BookgenericsCreateAPIView.as_view()),

from rest_framework.generics import CreateAPIView
class BookgenericsCreateAPIView(CreateAPIView):
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer
    def post(self, request, *args, **kwargs):
        return self.create(request)

结果:

3.5.3.2 ListAPIView

返回多个数据,实现了get方法:path('books/',views.BookgenericsListAPIView.as_view()),

from rest_framework.generics import ListAPIView
class BookgenericsListAPIView(ListAPIView):
    """
    Concrete view for listing a queryset.
    """
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer
    def get(self, request, *args, **kwargs):
        return self.list(request)

结果:

3.5.3.3 ListCreateAPIView

路由:path('books//',views.BookgenericsListCreateAPIView.as_view()),

from rest_framework.generics import ListCreateAPIView
class BookgenericsListCreateAPIView(ListCreateAPIView):
    """
    Concrete view for listing a queryset or creating a model instance.
    """
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer
    def get(self, request, pk):
        return self.list(request, pk)

    def post(self, request,pk):
        return self.create(request,pk)

结果:
post添加数据:

get获取数据:

3.5.3.3 RetrieveAPIView

返回单个数据,实现了get方法,路由:path('books/',views.BookgenericsRetrieveAPIView.as_view()),

from rest_framework.generics import RetrieveAPIView

class BookgenericsRetrieveAPIView(RetrieveAPIView):
    """
    Concrete view for retrieving a model instance.
    """
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer
    def get(self, request, *args, **kwargs):
        return self.retrieve(request)

结果:

3.5.3.4 UpdateAPIVIew

更新数据,实现了put方法和patch方法,路由:path('books//',views.BookgenericsUpdateAPIView.as_view()),

from rest_framework.generics import UpdateAPIView
class BookgenericsUpdateAPIView(UpdateAPIView):
    """
    Concrete view for updating a model instance.
    """
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer
    def put(self, request, *args, **kwargs):
        return self.update(request)

    def patch(self, request, *args, **kwargs):
        return self.partial_update(request)

结果:
put修改数据:

patch修改数据:

3.5.3.5 DestoryAPIView

删除数据,实现了delete方法,路由: path('books//',views.BookgenericsDestroyAPIView.as_view()),

from rest_framework.generics import DestroyAPIView
class BookgenericsDestroyAPIView(DestroyAPIView):
    """
    Concrete view for deleting a model instance.
    """
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器类
    serializer_class = BookInfoSerializer
    def delete(self, request, *args, **kwargs):
        return self.destroy(request)

结果:

3.5.4 视图集
  • 视图集不需要按照请求方式来定义方法名,但是需要在as_view中实现请求方式和方法名的映射关系
  • 常用的视图集
    • ViewSet

      • 继承自APIView和ViewSetMixin
      • ViewSetMixin主要实现了as_view中请求方式和方法名的映射处理
    • GenericViewSet

      • 继承自GenericAPIView和其他的扩展类

结束语

  本文属于作者原创,转载请注明出处,不足之处,希望大家能过给予宝贵的意见,如有侵权,请私信。每天一个小知识,一起学python,让技术无限发散

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/921413.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存