首页 > 编程语言 >环境变量和python多版本共存,视图层源码分析,视图层总结,路由层,

环境变量和python多版本共存,视图层源码分析,视图层总结,路由层,

时间:2024-07-30 20:50:28浏览次数:10  
标签:get python self 视图 环境变量 源码 import class serializer

Ⅰ 环境变量和python多版本共存

【一】环境变量

【1】什么是环境变量

  • 无论是win,mac,linux 都有环境变量的概念,以win为例什么是环境变量?
  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息

【2】win如何配置环境变量

我的电脑-->右键属性-->高级系统设置-->环境变量
    有两套:win,mac, linux都一样
    	用户环境变量:操作系统是分用户,用户环境变量配置的只针对于当前用户
        	如果换了其他用户登录进来,用不到别的用户的环境变量的
        系统环境变量:针对于操作系统,不分用户
        	所有用户进来,都会有相应的环境变量

【3】 打印出环境变量(你环境变量已有的让其在cmd打印出)

  • 打开Terminal,cmd
    • mac,linux输入 : echo $MS_PWD
    • win输入 : echo %MS_PWD%

【4】在环境变量中有个非常重要的参数:PATH (重点)

里面放了很多路径
    win:  以 ; 分割
    mac,linux :以 : 分割
    这堆路径的作用:
    	以后在命令行中敲一个命令(xx.bat,xx.exe),命令是否会执行
        先在当前目录下查找这个命令,如果能找到,直接就执行了(比如cd)
        如果找不到,会按照 PATH配置的目录,从上往下(前往后),依次查找,找到就执行
        如果还找不到,就报错,说:不是内部或外部命令,也不是可运行的程序
或批处理文件。
	   -如果PATH的环境变量中 的目录中,有多个同名的 【可运行的程序】,会先运行前面的,后面的就运行不了

【5】如果向让一个可执行文件,在任意路径下都能执行,必须把它所在路径加入环境变量PATH

-比如:django-admin 创建django项目
    	-E:\python\python310\Scripts\  在环境变量PATH中,django-admin.exe
        -E:\python\python310\  在环境变量PATH中,python.exe
        -E:\python\python310\Scripts\  在环境变量PATH中,pip.exe
        
    -mysql 客户端链接数据库
    	-E:\MYSQL8\mysql-8.4.2-winx64\bin 在环境变量PATH中 mysql mysqld

【二】python多版本共存 (简易介绍及其操作)

【1】下载安装包

为了测试,我下载版Python2.x和Python3.x版本,下载地址:https://www.python.org/downloads/

【2】安装python版本兼容的原理

安装多个版本的方法就是避免变量重名的情况,比如python2.x和python3.x版本安装完毕后都有默认的python执行脚本和一个pip的脚本,我们只需要在path环境中让他们找到各自的脚本名称就可以轻松实现多版本安装啦!

【3】配置Python2.x的环境变量

(1)安装完毕后将服务python脚本进行改名操作

(2)删除python2.x版本自带的脚本

(3)将python2.x加入windows系统的环境变量中

【4】安装Python3.x

(1)安装完毕后将服务python脚本进行改名操作

(2)删除Python3.x版本自带的脚本

  • 重复2.x版本步骤

(3)将python2.x加入windows系统的环境变量中

【4】在cmd中分别运行两个版本python

  • python2跟python3

Ⅱ 视图层源码分析

【一】两个视图基类

# APIViwe
   【1】 继承自django的View,必须写 get,post,delete。。。
   【2】 类属性:parser_class,render_class
    	  使用顺序是:视图类自己-->项目配置文件-->drf内置配置
    	  render_class=api_settings.DEFAULT_RENDERER_CLASSES
          api_settings是drf的配置,如果自己项目配置文件配了  REST_FRAMEWORK={},会覆盖掉原来drf默认的配置
   【3】 读APIViwe-->as_view和dispatch
    # 能从里面得到
    	(1) 包装了新的request: 
                新的request对象:request._request
                 视图类的对象 :self.requset 就是新的request
        (2) 去除了csrf认证
        		csrf_exempt(view)
        (3) 做了三大认证:认证,权限,频率
                self.perform_authentication(request)
                self.check_permissions(request)
                self.check_throttles(request)
        (4) 做了全局异常处理:后续要了解定制返回格式
        		在try里
   【4】 总结:
    def get(self,request):
        # request 新的
        # csrf校验没了
        # 执行完三大认证,才能到这里
        # 出了异常,会有捕获
    request._request
    self.request=request
    
    
    
# GenericAPIView
    【1】 继承了APIView--->APIView具备的所有特点,它都有,GenericAPIView更多一些
    【2】 多了几个类属性
    	queryset            # 数据源,直接给列表 或 QuerySet
        serializer_class    #  序列化类
        lookup_field = 'pk' # get_object,根本没传参数,但它指定是按pk拿
    	lookup_url_kwarg = None #lookup_url_kwarg=1 
    	filter_backends = api_settings.DEFAULT_FILTER_BACKENDS # 过滤
    	pagination_class = api_settings.DEFAULT_PAGINATION_CLASS # 分页
        
        
   【3】 多了几个方法:
		 get_queryset:本质就是返回了self.queryset 数据源
            def get_queryset(self):
                queryset = self.queryset
                if isinstance(queryset, QuerySet):
                    queryset = queryset.all() # 因为self.queryset 会先执行-->为了保证数据最新
                return queryset
         get_serializer:直接实例化得到序列化类的对象-->self.serializer_class
            def get_serializer(self, *args, **kwargs):
                serializer_class = self.get_serializer_class()
                kwargs.setdefault('context', self.get_serializer_context())
                return serializer_class(*args, **kwargs)
            def get_serializer_class(self): # 通过重写它,定制序列化,反序列化使用不用序列化类
                return self.serializer_class
            
           # 总结:
        	内部方法中拿序列化类的对象:get,post-->都是通过self.get_serializer()
            但是我们可以通过【重写】get_serializer_class,返回不同序列化类来控制:self.get_serializer()拿到的序列化类不同
            # 例如
                #  要求,序列化用 BookSerialzier 序列化类,反序列化用 BookWriteSerialzier
                class BookView(ListCreateAPIView):
                    queryset = Book.object.all()
                    serializer_class = BookSerialzier   
                    def get_serializer_class(self):
                        if self.request.method=='GET':
                            return BookSerialzier
                        else:
                            return BookWriteSerialzier

            
        get_object:根据 lookup_field 指定的对应参数,从数据源中 过滤出单个对象
        	
            
         def filter_queryset(self, queryset): # 过滤用的,后面了解
         XX_paginated_xx # 跟分页相关,后面了解
  • GenericAPIView的源码数据

【二】5个视图扩展类

# CreateModelMixin # GenericAPIView+create方法-->新增记录


class CreateModelMixin:
    def create(self, request, *args, **kwargs):
        # 拿到序列化类,实例化得到对象
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer) # 把它单独封装成方法的目的?
        # 通过重写 perform_create 在保存直接或之后干xx事
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    def perform_create(self, serializer):
        # 之前干的事
        serializer.save()
        # 之后干的事

ListModelMixin::list
	-获取所有
DestroyModelMixin:destroy
	-删除
    -perform_delete
RetrieveModelMixin:retrieve
	-拿单条
UpdateModelMixin:update
	-更新
    -perform_update

【三】9个视图子类

CreateAPIView:
	-GenericAPIView+CreateModelMixin+post方法
    -只写一个新增接口
    class BookView(CreateAPIView):
        queryset=xx
        serializer_class=yy
        def perform_save(self):
            pass
        def get_serializer_class(self):
            return zz
-ListAPIView:
	-GenericAPIView+ListModelMixin+get方法
    -只写一个查询所有接口
    class BookView(ListAPIView):
        queryset=xx
        serializer_class=yy
-DestroyAPIView:
	-GenericAPIView+DestroyModelMixin+delete方法

-UpdateAPIView:
	-GenericAPIView+UpdateModelMixin+put方法
-RetrieveAPIView:
	-GenericAPIView+RetrieveModelMixin+get方法
-ListCreateAPIView:
	-GenericAPIView+ListModelMixin+CreateModelMixin+post方法+get方法
    -写一个查询所有接口和新增接口
    class BookView(ListCreateAPIView):
        queryset=xx
        serializer_class=yy
-RetrieveUpdateDestroyAPIView
	-GenericAPIView+RetrieveModelMixin+UpdateModelMixin++DestroyModelMixin+put方法+get方法+delete方法
    -写一个查询单条,修改一条,删除一条
    class BookView(RetrieveUpdateDestroyAPIView):
        queryset=xx
        serializer_class=yy
-RetrieveDestroyAPIView,
-RetrieveUpdateAPIView

【四】视图集

# ModelViewSet,ReadOnlyModelViewSet,  ViewSetMixin,   ViewSet,GenericViewSet
# ModelViewSet:5个接口都有里面没有get,post,delete方法了,因为路由写法变了,是映射的
    CreateModelMixin
    ListModelMixin
    DestroyModelMixin
    RetrieveModelMixin
    UpdateModelMixin
    GenericViewSet
        -GenericAPIView
        -ViewSetMixin

#ReadOnlyModelViewSet:查询单条和所有接口
    ListModelMixin
    RetrieveModelMixin
    GenericViewSet
        -GenericAPIView
        -ViewSetMixin
        
        
# ViewSetMixin:控制路由写法变了的类。以后只要路由写法变了,必须继承它
	-重写了as_view,必须传字典做映射的方式,否则报错
    	-原理是通过反射:实现了MyViewSet.as_view({'get': 'list', 'post': 'create'})
        -要执行get的时候,本质执行的是 list
        
    -好处,以后视图类,可以写任意名字的方法,只要路由做好映射即可
    	-路由:path('send_sms/', UserView.as_view({'get':'send_sms'})),
        -视图类:
        class UserView(ViewSetMixin,APIView):
            def send_sms(self):
                print('真发短信')
                return Response({'code':100,'msg':"短信发送成功"})
#   ViewSet= ViewSetMixin,APIView



# GenericViewSet=ViewSetMixin+GenericAPIView
# 登录
from rest_framework.response import Response
class UserDetailView(GenericViewSet):
    serializer_class = 某个序列化类
    def login(self):
        serializer=self.get_serializer()
        serializer.is_valiad()
        return Response({'code':100,'msg':"短信发送成功"})

Ⅲ 视图层总结-小案例选择哪些视图类继承

# 【1】 发送短信接口   
	-APIView+get方法
    -ViewSet+send_sms方法
# 【2】 查询所有,查询单条
	-路由:
        path('books/', BookView.as_view({'get':'list'})),
        path('books/<int:pk>', BookView.as_view({'get':'retrieve'})),
    -视图类
    	class BookView(ReadOnlyModelViewSet):
            queryset=
            serializer_class=
            
# 【3】 查询所有,删除一条
	-写俩:ListAPIView   DestroyAPIView
    -写一个:
    -路由:
        path('books/', BookView.as_view({'get':'list'})),
        path('books/<int:pk>', BookView.as_view({'delete':'destroy'})),
    -视图类
    	class BookView(GenericViewSet,ListModelMixin,DestroyModelMixin):
            queryset=
            serializer_class=
            
            
# 【4】 总结
	1 只要向路由变了:ViewsetMixin
    2 只要想序列化,反序列化,就用GenericAPIView
    3 即想路由变了又想序列化,反序列化  GenericViewSet
    4 即想路由变了又想序列化,反序列化 ,还想写某一个或某几个接口 GenericViewSet+5个视图扩展类

Ⅳ 路由层

【一】继承 ViewSetMixin

# 只要继承 ViewSetMixin 的子类--->路由写法就变成了
	变成映射方式

【二】 drf提供了两个视图类,实现,不用映射,直接通过类 实例化得到对象方式,自动注册路由

# 【1】 导入一个类
    	from rest_framework.routers import SimpleRouter,DefaultRouter
# 【2】 类实例化得到对象
    	router=DefaultRouter()
# 【3】 注册视图类
    	router.register('books',BookView,'books')
# 【4】 在总路由中注册
		方式一:
        urlpatterns = [
   			path('', include(router.urls)), # 方式一:把自动生成的路由注册进总路由
		]
    	方式二:urlpatterns+=router.urls
from django.contrib import admin
from django.urls import path, include
from .views import BookView,PublisherView

from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('books',BookView,'books') # 自动映射 'get': 'list', 'post': 'create' 'get': 'retrieve', 'put': 'update', 'delete': 'destroy'

# router.register('publishers',PublisherView,'publishers')

print(router.urls)
# [<URLPattern '^books/$' [name='books-list']>,
# <URLPattern '^books\.(?P<format>[a-z0-9]+)/?$' [name='books-list']>,
# <URLPattern '^books/(?P<pk>[^/.]+)/$' [name='books-detail']>,
# <URLPattern '^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='books-detail']>,
# <URLPattern '' [name='api-root']>,
# <URLPattern '<drf_format_suffix:format>' [name='api-root']>]

# from app01.views import UserView
urlpatterns = [
    # path('books/', BookView.as_view({'get': 'list', 'post': 'create'})),
    # path('books/<int:pk>/', BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    # path('', include(router.urls)), # 方式一:把自动生成的路由注册进总路由
]
urlpatterns += router.urls   # 方式二

【三】 DefaultRouter 和SimpleRouter 区别

DefaultRouter 生成路径更多-->生成一个根

SimpleRouter 则会直接报错
  • DefaultRouter

  • SimpleRouter

【四】action装饰器

# 导入
from rest_framework.decorators import action  

# 使用
@action(methods=['methods'],detail=False)

# 装饰器源码 def action(methods=None, detail=None, url_path=None, url_name=None, **kwargs):
@action()
action装饰器可以接收两个参数:
    methods: 声明该action对应的请求方式,列表传递
        # methods=请求方式,可以有多个, 
    detail: 声明该action的路径是否与单一资源对应,及是否是xxx/<pk>/action方法名/
        True 表示路径格式是xxx/<pk>/action方法名/
        False 表示路径格式是xxx/action方法名/
        # 如 False: api/v1/books/login/   True: api/v1/books/4/login/  用的少
   	url_path=None # 路径名字,不写默认以方法名,如果 url_path=aa ---》api/v1/books/aa/
	url_name=None # 反向解析用,不用了

【五】继承了ViewSetMixin ,视图类中可以定义跟请求方式不同名的方法做映射(重点)

  • models.py
from django.db import models


# Create your models here.
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField()
  • app01\urls.py
from django.contrib import admin
from django.urls import path, include
from .views import BookView,PublishView

from rest_framework.routers import DefaultRouter,SimpleRouter
router = DefaultRouter()
router.register('books',BookView,'books') # 自动映射 'get': 'list', 'post': 'create' 'get': 'retrieve', 'put': 'update', 'delete': 'destroy'

router.register('publish',PublishView,'publish')

print(router.urls)
# [<URLPattern '^books/$' [name='books-list']>,
# <URLPattern '^books\.(?P<format>[a-z0-9]+)/?$' [name='books-list']>,
# <URLPattern '^books/(?P<pk>[^/.]+)/$' [name='books-detail']>,
# <URLPattern '^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='books-detail']>,
# <URLPattern '' [name='api-root']>,
# <URLPattern '<drf_format_suffix:format>' [name='api-root']>]

# from app01.views import UserView
urlpatterns = [
    # path('books/', BookView.as_view({'get': 'list', 'post': 'create'})),
    # path('books/<int:pk>/', BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    # path('', include(router.urls)), # 方式一:把自动生成的路由注册进总路由
    path('', include(router.urls)), # 方式一:把自动生成的路由注册进总路由
]
urlpatterns += router.urls   # 方式二
  • serializer.py
from .models import Book
from rest_framework import serializers


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
        # exclude=['id','name']  exclude 的意思是不包括哪些字段
  • views.py
from django.shortcuts import render
from rest_framework.response import Response

from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializer import BookSerializer

from rest_framework.decorators import action

class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer


    @action(methods=['POST'], detail=False)
    def login(self, request, *args, **kwargs):
        print('登陆成功')
        return Response({'code': 200, 'msg': '登陆成功'})


class PublishView(ModelViewSet):
    # api/v1/publish/send_sms/--->post请求就会触发它执行
    @action(methods=['POST'], detail=False)
    def send_sms(self, request):
        print('发送短信成功')
        return Response({'code': 100, 'msg': '发送短信成功'})

【六】在 视图类的对象中,有action参数,sele.action就是方法名的字符串

  • models.py
from django.db import models


# Create your models here.
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField()
  • urls.py
from django.contrib import admin
from django.urls import path, include
from .views import BookView

from rest_framework.routers import DefaultRouter,SimpleRouter
router = DefaultRouter()
router.register('books',BookView,'books') # 自动映射 'get': 'list', 'post': 'create' 'get': 'retrieve', 'put': 'update', 'delete': 'destroy'

urlpatterns = [
    
    path('', include(router.urls)), # 方式一:把自动生成的路由注册进总路由
]
urlpatterns += router.urls   # 方式二
  • serializer.py
from .models import Book
from rest_framework import serializers


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        # fields = '__all__'
        exclude=['id','name']  # exclude 的意思是不包括哪些字段
class BookWriteSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
  • views.py
from rest_framework.response import Response

from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializer import BookSerializer


#  序列化和反序列化用不同序列化类
from rest_framework.decorators import action
from .serializer import BookWriteSerializer


class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get_serializer_class(self):
        if self.action == 'list' or self.action == 'create':
            return BookSerializer
        elif self.action == 'retrieve' or self.action == 'destroy' or self.action == 'update':
            return BookWriteSerializer
        elif self.action=='login':
            return BookSerializer
    @action(methods=['POST'], detail=False)
    def login(self, request):
        print('登录成功')
        return Response({'code': 100, 'msg': '登录成功'})

标签:get,python,self,视图,环境变量,源码,import,class,serializer
From: https://www.cnblogs.com/zyb123/p/18333336

相关文章

  • Python面试题:如何使用Django Rest Framework构建RESTful API
    使用DjangoRestFramework(DRF)构建RESTfulAPI是一个常见且强大的方法。以下是一个详细的指南,帮助你从头开始创建一个基本的Django项目,并使用DRF构建一个RESTfulAPI。环境准备安装Django和DjangoRestFramework:pipinstalldjangodjangorestframewor......
  • python高性能计算:cython入门代码
    三种实现的对比:(1)纯pythonx.pydefis_prime(num):forjinrange(2,num):if(num%j)==0:returnFalsereturnTrueimporttimea=time.time()foriinrange(10,100000):is_prime(i)b=time.time()print(b-a)(2)x2.py......
  • 【第二节】python编程基础语法
    目录一、运算符介绍1.1算术运算符1.2比较运算符1.3赋值运算符1.4位运算符1.5逻辑运算符1.6成员运算符1.7身份运算符二、python运算符优先级三、三大流程结构四、列表五、元组六、字典一、运算符介绍1.1算术运算符1.2比较运算符1.3赋值运算符......
  • 基于python的百度迁徙迁入、迁出数据分析(四)
    这篇文章是对上篇文章的可获取数据的时间区间的修正,依然通过开发者模式找寻相关数据源,我直接把数据url贴在这里,可以发现里面包含了相对明面上看不到的数据包括,行政区id、春运迁徙数据等:qianxi.cdn.bcebos.com/app/index.js?9bf6150c2c2807aeaddb上篇文章在这里,有兴趣的可以连......
  • python高性能计算:cython使用openmp并行 —— 报错:undefined symbol: omp_get_thread_n
    test.pyx文件:fromcython.parallelcimportparallelfromopenmpcimportomp_get_thread_numcpdefvoidlong_running_task1()noexceptnogil:whileTrue:passcpdefvoidlong_running_task2()noexceptnogil:whileTrue:passdefdo......
  • 使用Python Paramiko创建文件目录并上传文件的终极指南
    哈喽,大家好,我是木头左!前言:为何选择Paramiko?在网络运维和自动化领域,SSH(SecureShell)协议是连接和管理远程服务器的常用手段。而Paramiko是一个用于进行SSH2会话的Python库,它支持加密、认证和文件传输等功能。使用Paramiko,可以方便地实现远程命令执行、文件上传下载等操作。准......
  • python_爬虫基础
    python爬虫基础1、初识爬虫1.rebots协议网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取,但它仅仅是互联网中的约定而已,可以不用遵守。例如:https://www.taobao.com/robots.txt2.谷歌浏览器插件●XPathHelper●WebScraper●ToggleJavaScript●User-......
  • Python - Creating Managed Attributes using properties
    CreatingManagedAttributesusingpropertiesPropertiescanbeusedtocreatedataattributeswithspecialfunctionality.Ifyouwantsomeextrafunctionality(liketypechecking,datavalidationortransformation)whilegettingorsettingadataattribut......
  • 基于SpringBoot+Vue的电影院订票信息管理系统的详细设计和实现(源码+lw+部署文档+讲解
    文章目录前言详细视频演示项目运行截图技术框架后端采用SpringBoot框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • 基于SpringBoot+Vue的甘肃旅游管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示项目运行截图技术框架后端采用SpringBoot框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......