Django路由层之路由分发 名称空间 虚拟环境 视图层之三板斧 JsonRsponse对象 request对象获取文件 FBV与CBV CBV源码剖析 模板层
阅读原文时间:2023年07月08日阅读:1

目录

路由层之路由分发

Django支持每个应用都可以自己独立的路由层、静态文件、模板层。基于该特性多人开发项目就可以完全解耦合,之后利用路由分发还可以整合到一起

多个应用都有很多路由与视图函数的对应关系 这时候可以拆分到各自的路由层

由总路由去管理子路由

使用路由分发之前 总路由直接干路由与视图函数的匹配

    path('index/', views.index)

使用之后分发之后,总路由只按照应用名分配匹配方向

    path('app01/', include('app01.urls'))

路由层之名称空间

路由分发之后 针对相同的别名能否自动反向解析出不同的应用前缀?

在每个应用层下的路由中取一样的别名

默认情况下是无法识别应用前缀的

想要正常识别区分有两种方式:

在总路由

 path('app01/', include(('app01.urls', 'app01'), namespace='app01')),
path('app02/', include(('app02.urls', 'app02'), namespace='app02')),

反向解析

        reverse('app01:index_view')
        reverse('app02:index_view')

多个应用别名不冲突可以用应用名作为别名的前缀

            path('index/', views.index, name='app01_index_view')
         path('index/', views.index, name='app02_index_view')

虚拟环境

是搭配requirements.text(记录所需的模块以及版本)一起使用这样就能自动下载所需的模块及版本

需求:

项目1需要使用:django1.11                                              python38
项目2需要使用:django2.22 pymysql requests                python38
项目3需要使用:django3.22 request_html flask urllib3     python38
等等...

实际开发项目中我们只会给项目配备所需的环境,不需要的一概不配,这样就可以节省资源

虚拟环境:能够针相同版本的解释器创建多个分身 每个分身可以有自己独立的环境

venv虚拟环境代名词

创建出来的就是一个全新的解释器

下载Django1.1版本如出现报错 要学会看报错信息

将如上代码复制 并且也会同时下载所需相关联的模块

在命令行中虚拟环境是不支持多版本共存的

所以当你在终端以命令行形式创建虚拟环境python -m venv python38venv(创建虚拟环境的名字) 会取决于你环境变量解释器的查找顺序

进入虚拟环境查看目录结构dir

激活虚拟环境

方式1. 直接激活虚拟环境:source activate 虚拟环境名字

方式2. 进入到Scripts目录下调用activate激活:python38venv/scripts/activate

关闭虚拟环境:

进入到Scripts目录下python38venv/scripts/deactivate

视图层之三板斧

用来处理视图函数都必须得返回HttpRsponse对象 完全正确
class HttpResponse:
    pass
return HttpResponse()    

def render():
    return HttpResponse()
return render()

def redirect():
    redirect_class = 类(祖先有个类是HttpResponse)
    return redirect_class()
return redirect()

在视图层中定义函数什么都不返回 pass HttpRsponse其实就是个类

报错显示没有返回一个HttpRsponse对象

返回的也是HttpRsponse对象

本质的本质也是返回的HttpRsponse对象

视图层之JsonResponse对象

给浏览器返回一个json格式字符串 使用json模块序列化可以实现

但在Django里有一个更方便的JsonResponse

前后端交互一般使用Json格式 而字典使用频率是最高的(表现数据的形式比较精准)JsonResponse默认是对字典做序列化

查看源码底层还是Json模块 Jsonresponse底层帮你封装了json模块。这里双下init里的data就是我们传进去的数据(必须是json模块支持转换的数据之一)

解决json中文乱码问题:

JsonRsponse解决编码问题:

可以通过给Jsonresponse传参数,将{ensure_ascii = utf8}这个字典传入内部封装的json.dumps。然后通过双星号解包,作为json.dumps的关键字实参传进去:

把字典换成一个列表去序列化

如图会显示报错 为了允许一个非字典的对象被序列化要把参数safe设置成False 由源码知safe默认是True 把safe改成False

json.JSONEncoder 查看那些数据类型能够被序列化

这样列表就能够被序列化

JsonResponse主要序列化字典 针对非字典的其他可以被序列化的数据需要修改safe参数为False

PS:以后写代码很多时候可能需要参考源码及所学知识扩展功能

视图层之request对象获取文件

form表单携带文件按类型的数据需要做到以下几点:

1.method是post

2.enctype是multipart/form-data(记form-data人家就知道什么意思)

针对选择类标签用户是不输的值value得设定好

Django后端需要通过request.FILES获取文件类型的数据

上图中file名字是由前端name属性指定的

request.FILES.get获取单个文件(getlist多个文件)拿到的是一个对象

将拿到的文件数据保存

如果我们要指定存储文件我们可以通过os模块做拼接 根目录就不用再获取了直接从settings里面的BASE_DIR拿到项目根目录 再路径拼接 创建文件mkdir

视图层之FBV与CBV

基于函数的视图

def index(request):return HttpResponse对象

基于类的视图(使用更加的灵活)

    from django import views
       class MyLoginView(views.View):
        def get(self, request):
            return HttpResponse('from CBV get function')

        def post(self, request):
            return HttpResponse('from CBV post function')
    path('login/', views.MyLoginView.as_view())
    会自动根据请求方法的不同自动匹配对应的方法并执行

需要导一个模块views

只要在类里面写跟请求方法相同的函数名 当在朝类发送请求的时候 如果你是get/post就会自动触发对应方法的执行 如果是其他的请求只要定义了对应的方法就会自动触发执行

CBV 路由也要做相应变化 类名点as_view()

CBV源码剖析(非常重要)

path('login/', views.MyLoginView.as_view())
        1.类名点名字(类或对象点名字涉及名字的查找顺序问题 先从本身查找) MyLoginView.as_view()
        2.类名点名字并加括号调用(静态方法、绑定给类的方法)

myloginview是我们定义的视图类,其中有get和post两个方法。

所以我们先从myloginview类中找as_view这个名字,而我们自己创建的类是没有as_view() 那么往父类里面找 没有那么肯定会报错的,所以往父类找(views.View)。

因为是在类中调用as_view(),所以初步判断as_view()应该是个 类方法 或者 是个静态函数

如图可以看出是一个绑定给类的静态方法

发现view是个闭包函数,as_view执行之后将view作为返回值传出去。返回出去的view函数执行时可以用到外层as_view函数名称空间的名字(闭包)

类名加括号调用一个函数拿到一个返回值view

    path('login/', views.view)  # CBV路由本质还是FBV

    1.产生我们自己编写类的对象
     2.对象调用dispatch方法(注意查找顺序)

核心(清楚self是谁) 产生我们自己编写类的对象

浏览器访问路由,会执行内层函数view(自动加括号调用)。也就是通过view类产生一个对象。

查看view函数源码:

这里的cls是我们自己创的视图类。view的外层函数是as_wiew。as_wiew是个类方法。我们通过类调用会将类本身作为第一参数传进去也就是这里的cls 查找顺序是先对象本身 再找产生对象的类 然后再找父类

获取当前请求方法并转小写 之后利用反射获取类中对应的方法并执行

使用反射getatter 通过不同的请求 获取视图类中的方法赋值给handler

此时handler就是我们视图类中的get、post函数

口述CBV

class View:
     @classmethod
     def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            return self.dispatch(request, *args, **kwargs)
     def dispatch(self, request, *args, **kwargs):
         handler = getattr(self, request.method.lower())
         return handler(request, *args, **kwargs)

模板层

"""
{{}}:主要与数据值相关
{%%}:主要与逻辑相关

django的模板语法是自己写的 跟jinja2不一样

1.针对需要加括号调用的名字 django模板语法会自动加括号调用你只需要写名字就行
2.模板语法的注释前端浏览器是无法查看的 {##}
3.
"""


   return render(request, 'demo02.html', {'n1': name, 'a1': age})  # 传值方式1:精准传值 不浪费资源 针对多资源的传递书写麻烦

    return render(request,'demo02.html', locals())  # 传值方式2:将函数名称空间中所有的名字全部传递 名字过多并且不使用的情况下比较浪费资源

    1.基本数据类型正常展示
    2.文件对象也可以展示并调用方法
    3.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)
    4.类名也会自动加括号调用
    5.对象则不会
     ps:总结针对可以加括号调用的名字模板语法都会自动加括号调用 Django模板语法不支持传参数

1.基本数据类型正常展示、2.文件对象也可以展示并调用方法

3.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)

4.类名也会自动加括号调用 5.对象则不会 对象可以点它的方法

类自动加括号

过滤器能接收的最大长度 右|右各一个 共两个

add 做字符拼接及求和

add源码

length 获取字符长度

slice 切片

更多:https://www.cnblogs.com/Dominic-Ji/articles/10982302.html