drf知识-06

视图集

#1  ModelViewSet:
视图类:GenericAPIView
映射:list  create  retrieve update destroy
#2  ViewSetMixin类: 只要继承它,路由写法变了         
    分析:ViewSetMixin  不是视图类,支持路由映射的写法,核心原理是重写了as_view 
            以后路由写法as_view必须传字典,映射关系
            什么请求方式就执行视图类中什么方法的映射关系  

       @classonlymethod
    def as_view(cls, actions=None, **initkwargs):
        # actions={'get': 'list', 'post': 'create'}
       def view(request, *args, **kwargs):
            self = cls(**initkwargs)  # self 是BookView 视图类的对象
            self.action_map = actions
            for method, action in actions.items():
                # method:get   action:list
                # 去视图类的对象中 self中 反射list方法---》有--》
                # handler 就是 BookView的对象中得list方法
                handler = getattr(self, action)
                # 反射,设置值---》把method:get,设置成了 list
                #BookView类的对象,以后get方法就是list方法
                setattr(self, method, handler)
            # 根据请求方式执行跟请求方式同名的方法  get请求---》get方法---》list
            return self.dispatch(request, *args, **kwargs)

#3  ViewSet:以后想继承APIView,但是路由写变了,就继承它
#4  GenericViewSet:以后想继承GenericViewSet,但是路由写变了,就继承它
#5 ReadOnlyModelViewSet:只读
    视图类:GenericAPIView
    映射:list    retrieve :只查询,查询所有和查询单条ListModelMixin,RetrieveModelMixin
    路由写法变了:ViewSetMixin

小案例选择哪些视图类继承

### 现在有很多视图类,不知道选哪个,具体实战
# 1 publish的5个接口:

        ModelViewset

# 2 publish的5个接口,获取所有,带code和msg:

        ModelViewset重写list

def list(self, request, *args, **kwargs):
    res = super().list(request, *args, **kwargs)
    return Response({'code': 100, 'msg': '查询所有成功', 'result': res.data})

# 3 写 查询所有,修改一条,路由写法变了
    ViewSetMixin, GenericAPIView
    ListModelMixin,UpdateModelMixin

# class BookView(ViewSetMixin, GenericAPIView,ListModelMixin,UpdateModelMixin):
class BookView(GenericViewSet,ListModelMixin,UpdateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

路由:
   path('books/', views.BookView.as_view({'get': 'list'})),
   path('books/<int:id>', views.BookView.as_view({'put': 'update'})),

# 4 用户视图类,有登录(login)和注册(register)接口


 

class UserView(ViewSet):
    def login(self):
        pass
    def register(self):
        pass

# path('login/', views.UserView.as_view({'post': 'login'})),
# path('register/', views.BookView.as_view({'post': 'register'})),

# 5 新增一条图书,路由写法变了

from rest_framework.generics import CreateAPIView
class BooView(ViewSetMixin,CreateAPIView):
    queryset = None
    serializer_class = None
    #path('books/', views.UserView.as_view({'post': 'create'})),

# 6 查询一条和删除

from rest_framework.generics import RetrieveDestroyAPIView
class BooView(RetrieveDestroyAPIView):
class BooView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin):
    queryset = None
    serializer_class = None

视图层总结

# 视图层:
# 两个视图基类
    APIView
    GenericAPIView
# 5个视图扩展类---》不是视图类,必须结合GenericAPIView
        CreateModelMixin:create---》原来咱们post中得代码,新增
        ListModelMixin:list---》原来获取所有
        RetrieveModelMixin:retrieve---》原来获取单条
        UpdateModelMixin:update--->修改
        DestroyModelMixin:destroy--》删除
# 9个视图子类
        CreateAPIView
        ListAPIView
        RetrieveAPIView
        DestroyAPIView
        UpdateAPIView
        ListCreateAPIView
        RetrieveUpdateDestroyAPIView
        RetrieveDestroyAPIView
        RetrieveUpdateAPIView           
# 视图集
    ModelViewSet:
    ReadOnlyModelViewSet:
    ViewSetMixin:路由写法变了
    ViewSet:ViewSetMixin+APIView
    GenericViewSet:ViewSetMixin+GenericAPIView

drf之路由

# 视图类没有继承了ViewSetMixin,路由写法跟之前一样
    path('books/', views.BookView.as_view())
#  只要视图类继承了ViewSetMixin,路由写法必须写成映射的方式
    path('books/', views.BookView.as_view({'get': 'list'})),
# 只要视图类继承了ModelViewSet,还可以这么写:

路由:
from rest_framework.routers import SimpleRouter  #1 导入
router = SimpleRouter()   #2 实例化
router.register('books', views.BookView, 'books')    #3 注册路径,action装饰器
urlpatterns = [
]
urlpatterns += router.urls    #4 加入到路由中
 
视图类:
from .models import Book
from .serializer import BookSerializer
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    # 5 list,create,retrieve,destroy,update自动映射--》SimpleRouter
    serializer_class = BookSerializer 
    @action(methods=['POST'],detail=False,)
    def login(self,request):
        return Response('login')

# 3 假设视图类中有个login,如何做对应?

from rest_framework.decorators import action
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    #methods=None, 请求方式
    # detail=None,  只能写True或False,如果写了false就是不带pk的路径,如果写了True路径带pk
        # False的情况: http://127.0.0.1:8080/api/v1/books/login/
        # True 的情况: http://127.0.0.1:8080/api/v1/books/8/login/
    # url_path='login' 路径,会在之前的路径上,拼这个路径,如果不写默认以函数名拼接
        # - http://127.0.0.1:8080/api/v1/books/login/
    # url_name=None :别名,用做反向解析
    @action(methods=['POST'],detail=False,)
    def login(self,request):
        return Response('login')

# 4 总结:以后只要继承ViewSetMixin,就可以使用SimpleRouter方式写路由

from rest_framework.routers import SimpleRouter,DefaultRouter  #1 导入
SimpleRouter,DefaultRouter     #2 实例化
router = SimpleRouter()
# router = DefaultRouter()
router.register('books', views.BookView, 'books')   #3 注册路径,action
#4 加入到路由中:
# 方式一:(用这个)
urlpatterns += router.urls
# 方式二:
urlpatterns = [
    path('', include(router.urls)),
]

# 5 list,create,retrieve,destroy,update--->自动映射--》SimpleRouter
# 6 视图类中自己的方法,再做映射--action装饰器

@action(methods=['POST'],detail=False,)
def login(self,request):
    return Response('login')

认证组件之登录认证

# 登录认证:
   登录进系统后,以后再访问接口,需要携带登录信息,如果没携带,不允许
    cookie(客户端浏览器上)和session(后端存储的键值对)
# 写个登录

from django.contrib import admin
from django.urls import path, include
from . import views
from rest_framework.routers import SimpleRouter, DefaultRouter

router = SimpleRouter()   # 实例化
router.register('books', views.BookView, 'books')    # 注册路径
# http://127.0.0.1:8080/api/v1/users/login---->post 请求就执行UserView的login方法
router.register('users', views.UserView, 'users')
urlpatterns = [
    path('', include(router.urls)),
]   # urlpatterns += router.urls
# 登录,对照数据库用户名或密码,若正确更新或添加token
from rest_framework.decorators import action
from .models import User, UserToken
import uuid
class UserView(ViewSet):
    @action(methods=['POST'], detail=False)
    def login(self, request):
        # 前端传入的username和password  request.data
        username = request.data.get('username')
        password = request.data.get('password')
        user = User.objects.filter(name=username, password=password).first()
        if user:
            token = str(uuid.uuid4())
            # 如果之前UserToken表中有记录,就要更新,如果没有记录,就要新增
            UserToken.objects.update_or_create(defaults={'token': token}, user_id=user.pk)
            return Response({'code': '100', 'msg': '登录成功', 'token': token})
        else:
            return Response({'code': '101', 'msg': '用户名或密码错误'})

# 后续访问某些接口,携带登录信息--->session--->后端校验(认证组件)

# 认证组件步骤:
    1 写个认证类,继承BaseAuthentication
    2 在类中重写 authenticate,在方法中完成认证,通过返回两个值,失败抛异常     

# 必须有token才能登录,通过token去user
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from .models import User, UserToken
class LoginAuth(BaseAuthentication):
    def authenticate(self, request):
        # 完成对用户的校验
        # 当次请求request
        token = request.query_params.get('token')
        # 表中校验
        user_token = UserToken.objects.filter(token=token).first()
        # 当前登录用户
        if user_token:
            user = user_token.user
            # 校验过后,返回两个值
            return user, user_token
        else:
            raise AuthenticationFailed("您没有登录")

3 使用认证类:放在需要登录后才能访问的视图类上

from .auth import LoginAuth
class BookView(ReadOnlyModelViewSet):  # list  retrieve
    authentication_classes = [LoginAuth]  # 5个接口必须登录才能呢访问
    # 配置两个类属性
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 重写list添加了信息显示
    def list(self, request, *args, **kwargs):
        res = super().list(request, *args, **kwargs)
        return Response({'code': 100, 'msg': '查询所有成功', 'result': res.data})

今日思维导图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/272421.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FTP不同方式使用与搭建与端口号常识了解

目录 一、FTP介绍 二、winServer2012搭建ftp服务器 在虚拟机搭建具体步骤 2.1、新建组&#xff1a; 2.2、新建用户名 2.3、把用户名与组绑定 2.4、安装ftp 2.5、配置ftp服务器 2.6、给文件夹调整权限 2.7、测试 a、服务器本机测试 b、外部机器测试 C、借助工具Mobal…

低代码开发:数字化转型的引擎

引言 在当今数字化时代&#xff0c;组织面临着不断变化的市场需求和技术挑战。数字化转型已成为维持竞争力的关键&#xff0c;而低代码开发正在崭露头角&#xff0c;成为加速创新和数字化转型的有力工具。本文将深入探讨低代码开发的核心概念、优势和应用&#xff0c;以揭示它…

数据库基础面试第四弹

1. Redis的数据结构有哪些 1. 字符串&#xff08;String&#xff09;&#xff1a; 字符串是Redis最基本的数据结构。它可以存储任意类型的数据&#xff0c;包括文本、整数或二进制数据。字符串类型的值最大可以达到512MB。 1 2 3 4 SET name "John" GET name 将字…

云原生Kubernetes:K8S集群版本升级(v1.22.14 - v1.23.14)

目录 一、理论 1.K8S集群升级 2.环境 3.升级集群&#xff08;v1.23.14&#xff09; 4.验证集群&#xff08;v1.23.14&#xff09; 二、实验 1. 环境 2.升级集群&#xff08;v1.23.14&#xff09; 2.验证集群&#xff08;v1.23.14&#xff09; 一、理论 1.K8S集群升级 …

【Python_09】Python基础语法(数据容器之列表详解)

文章目录 概述Python中的数据容器列表1.1 定义列表1.2列表取值与修改1.3 列表遍历1.3.1 使用for循环遍历列表1.3.2 使用while循环遍历1.3.3 使用enumerate()函数获取索引和元素 1.4 列表常用方法 概述 数据容器是用来存储和组织数据的数据结构和对象。可以以不同的方式存储和操…

摇杆控制人物移动

摇杆控制人物移动 一、UI搭建二、3d模型搭建三、脚本JoyStickBar.csPlayerController.cs 工程在我资源里名字叫Joystickbar.unitypackage [连接](https://download.csdn.net/download/qq_42194657/12043019?spm1001.2014.3001.5503) 一、UI搭建 JoyStickBar是图片背景 JoySt…

功能问题:如何在H5中实现拍照功能?3步搞定!

大家好&#xff0c;我是大澈&#xff01; 本文约2100字&#xff0c;整篇阅读大约需要4分钟。 感谢关注微信公众号&#xff1a;“程序员大澈”&#xff0c;免费领取"面试礼包"一份&#xff0c;然后免费加入问答群&#xff0c;从此让解决问题的你不再孤单&#xff01…

python 面试题第一弹

1. 如何理解Python中的深浅拷贝 浅拷贝&#xff08;Shallow Copy&#xff09;创建一个新的对象&#xff0c;该对象的内容是原始对象的引用。这意味着新对象与原始对象共享相同的内存地址&#xff0c;因此对于可变对象来说&#xff0c;如果修改了其中一个对象&#xff0c;另一个…

odoo17核心概念view7——listview总体框架分析

这是view系列的第七篇文章&#xff0c;今天主要介绍我们最常用的list视图。 1、先看list_view,这是主文件 /** odoo-module */import { registry } from "web/core/registry"; import { RelationalModel } from "web/model/relational_model/relational_mode…

Spring中常见的Bean后处理器

Bean后处理器的作用&#xff1a;为Bean生命周期各个阶段提供扩展。接下来我们查看一个案例 public class TestBeanPostProcessor {public static void main(String[] args) {//该容器不存在任何Spring中的bean对象&#xff0c;是一个干净的容器&#xff0c;且提供了正常容器中…

运动轨迹仿真

重型运载火箭轨迹/总体参数一体化优化方法 硬核推导火箭运动方程&#xff0c;并用python仿真实现 rocket-simulation:MATLAB-火箭仿真软件 MatRockSim:Matlab 火箭飞行模拟器 【开源】飞鹰一号探空火箭——箭体设计、制造回顾与仿真对比 偏航角&#xff0c;滚动角&#xf…

基于双闭环PI的SMO无速度控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于双闭环PI的SMO无速度控制系统simulink建模与仿真&#xff0c;基于双闭环PI的SMO无速度控制系统主要由两个闭环组成&#xff1a;一个是电流环&#xff0c;另一个是速度环。…

2024深入评测CleanMyMac X4.14.6破解版新的功能

随着时间的推移&#xff0c;我们的Mac电脑往往会变得越来越慢&#xff0c;存储空间变得越来越紧张&#xff0c;这时候一个优秀的清理工具就显得尤为重要。作为一款备受好评的Mac清理工具&#xff0c;它能够为你的Mac带来全方位的清理和优化。在本文中&#xff0c;我们将深入评测…

中科驭数与宽睿科技达成战略合作,共筑超低时延软硬一体技术底座

近日&#xff0c;中科驭数&#xff08;北京&#xff09;科技有限公司&#xff08;简称“中科驭数”&#xff09;和上海宽睿信息科技有限责任公司&#xff08;简称“宽睿科技”&#xff09;完成战略合作协议签署。双方将结合各自在超低时延软硬件领域的深厚业务积累和技术产品优…

晶振的起振温度对电子设备的影响

晶振&#xff0c;作为电子设备中的关键元件&#xff0c;其性能参数对设备的稳定性和可靠性具有重要影响。其中&#xff0c;晶振的起振温度是决定其工作性能的重要因素之一。晶发电子将探讨晶振起振温度对电子设备的影响以及如何应对这些影响。 首先&#xff0c;我们要了解什么…

2023/12/26中断作业

成果图&#xff1a; 代码&#xff1a; 函数层 key_it.c #include "key_init.h" void key1_it_config() { //RCC时钟RCC->MP_AHB4ENSETR |(0X1<<5);//设置PF9管脚为输入GPIOF->MODER &(~(0x3<<18));//设置PF9管脚为exti9输入EXTI->EXTI…

减小PAPR——DFT扩频

文章目录 前言一、DFT 扩频原理二、MATLAB 仿真1、核心代码2、仿真结果①、4QAM 调制时 IFDMA、LFDMA 和 OFDMA 的 DFT 扩频技术的 PAPR 性能②、16QAM 调制时 IFDMA、LFDMA 和 OFDMA 的 DFT 扩频技术的 PAPR 性能③、64QAM 调制时 IFDMA、LFDMA 和 OFDMA 的 DFT 扩频技术的 PA…

如何在Photoshop中创建色彩鲜艳的文本效果

如何在 Photoshop 中制作霓虹灯 1. 如何创建背景 步骤 1 学习如何在 Photoshop 中制作霓虹灯文本的第一步是背景。创建一个新的 1160 x 750 像素文档&#xff0c;并将分辨率设置为 300。 转到"文件">"嵌入位置"&#xff0c;然后打开"垃圾灰色砖…

tensorrt环境安装-可用于深度学习模型加速推理

安装python环境 在anaconda的命令行中输入conda create --name py38 python3.8 安装python环境 然后安装深度学习框架pytorch环境 Previous PyTorch Versions | PyTorch 在这里面选择合适的环境 conda install pytorch1.8.0 torchvision0.9.0 torchaudio0.8.0 cudatoolki…

汽车项目管理

项目节点&#xff1a; MR (Management Review)——管理层评审 KO (Kick Off)——项目正式启动 SI (Strategy Intent)——战略意图 SC (Strategy Confirmation)——战略确认 PA (Program Approval)——项目批准 PR (Product Readiness)——产品就绪 VP (Verification Prototype)…