首页 > 其他分享 >django框架(部分讲解)

django框架(部分讲解)

时间:2022-12-13 20:33:12浏览次数:73  
标签:框架 request 视图 django 虚拟环境 app01 讲解 路由 view

路由分发

  • django每个应用都可以有自己独立的路由层、静态文件、模板层。基于该特性多人开发项目就可以完全解耦合,之后利用路由分发还可以整合到一起
  • 多个应用都有很多路由与视图函数的对应关系 这个时候可以拆分到各自的路由层中
  • 说的直白一点,路由分发就是把Django项目中的路由信息分配到每个应用中,然后在项目的路由文件中导入应用中的路文件即可正常使用。

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

path('index/', index)

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

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

应用中的子路由:

path('after/',views.after)  # app01

path('after/',views.after)  # app02

总结:

  • 路由分发解决的就是项目的总路由匹配关系过多的情况
  • 利用路由分发之后 总路由不再处理路由与视图函数的直接对应关系
  • 总路由而是做一个分发处理(识别当前url是属于那个应用下的 直接分发对应的应用去处理)

名称空间

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

经过测试,默认情况下是无法直接识别应用前缀的。

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

方式1:名称空间

在总路由中增加一个名称空间(在Django1Django2及以上版本有区别,Django1用的是url

Django2及以上版本

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

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

反向解析中的使用方式

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

Django1中的使用方式

# 1.总路由增加一个名称空间
url(r'^app01/',include('app01.urls',namespace='app01')), # 创建名称空间app01
url(r'^app02/',include('app02.urls',namespace='app02'))  # 创建名称空间app02
# 2.子路由app01
urlpatterns = [
    url(r'^reg/',views.reg,name='reg')
]
# 后端
def reg(request):
    print(reverse('app01:reg'))
    return HttpResponse('app01: reg')

# 前端
{% url 'app01:reg' %}

# 3.子路由app02
urlpatterns = [
    url(r'^reg/',views.reg,name='reg')
]

# 后端
def reg(request):
    print(reverse('app02:reg'))
    return HttpResponse('app02: reg')
# 前端
{% url 'app02:reg' %}

方式2:别名不冲突即可

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

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

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

虚拟环境

项目1需要使用:django1.11 					 python38
项目2需要使用:django2.22 pymysql requests			      python38
项目3需要使用:django3.22 request_html flask urllib3		 python38
实际开发项目中我们只会给项目配备所需的环境,不需要的一概不配!!!

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

项目环境中,下载模块需要占用资源,所以我们争取项目要什么模块给什么模块,不需要的一点都不下。
每个项目需要独立的环境,每个环境只下载项目需要的依赖,不需要多的内容。虚拟环境的好处是可以隔离环境,随时切换环境。
    
pycharm创建虚拟环境:(每创建一个虚拟环境就相当于重新下载了一个全新的解释器)
命令行的方式: python -m venv pyvenv38
 
注意:python命令此处不支持多版本共存的操作 python27 python36 python38
    激活
        activate
    关闭
        deactivate
		
'''pip install --index-url http://mirrors.aliyun.com/pypi/simple/ django==1.11.11 --trusted-host mirrors.aliyun.com'''

虚拟环境的创建和使用:
pycharm创建虚拟环境(每创建一个虚拟环境就相当于重新下载了一个全新的解释器)

image

Inherit global site-packages:是否要继承当前环境的下载的第三方模块。视情况勾选

image

Make available to all projects:是否允许所有的项目使用该虚拟环境。可以勾选

虚拟环境在pycharm是黄色的:

image

使用虚拟环境下载模块:

image

虚拟环境创建 不支持多版本共存的操作:
只允许用python -m venv 虚拟环境名 这种格式创建
不支持这样创建python38 -m venv 虚拟环境名
所以我们要将python对应的python环境 在系统环境变量设置好 再进行虚拟环境的创建

虚拟环境更多:https://www.cnblogs.com/passion2021/p/16720214.html

视图层之必会三板斧

视图函数必返回httpresponse对象

视图函数不写返回值会报错:

image

查看源码我们可以得知:HttpResponse是个类 而类加括号可以产生对象

render返回的也是HttpResponse对象:只不过环的参数不一样:

image

redirect经过了多层继承,本质还是HttpResponse对象:

image

JsonResponse对象

JsonResponse也是在返回值中使用的 给浏览器返回的json格式的字符串

from django.http import JsonResponse
def index_func(request):
    # return HttpResponse('哈哈哈')
    # return render()
    # return redirect()
    # 返回给浏览器一个json格式的字符串
    user_dict = {'name': 'jason老师', 'age': 18}
    # import json
    # user_json = json.dumps(user_dict, ensure_ascii=False)
    # return HttpResponse(user_json)
    return JsonResponse(user_dict)

ps:以后写代码很多时候可能需要参考源码及所学知识扩展功能
	class JsonResponse():
        def __init__(self,data,json_dumps_params=None):
        		json.dumps(data,**json_dumps_params)
          
JsonResponse主要序列化字典 针对非字典的其他可以被序列化的数据需要修改safe参数为False

不使用JsonResponse,又想返回给浏览器的json格式的字符串:

image

此时浏览器还是当做字符串渲染。
字典中有中文时,设置ensure_ascii=False解决

使用Jsonresponse:
浏览器能识别jsonresponse

直接将字典放入该类
查看源码:

image

Jsonresponse底层帮你封装了json模块。这里双下init里的data就是我们传进去的数据(必须是json模块支持转换的数据之一)
解决json中文乱码问题:

image

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

image

Jsonresponse传列表的情况:

image

看报错:

image

jsonresponse默认是对字典进行序列化,如果要对列表进行序列化,需要传一个参数。将safe改成false

image

视图层之request对象获取文件

建立前端html页面:

image

我们写一个表单,这个表单包含提交文件的选项。众所周知,表单会发送post请求。那我们在视图函数使用request.POST可以获取到文件吗?
很遗憾,不能:

image

只能获取一个文件名,而不能获取到数据。
要想让django能获取到,需要修改表单标签的属性enctype

image

即:enctype="multpart/form-data"
请注意,这个属性你不修改,其默认是:
enctype="application/x-www-form-urlencoded"
简单介绍enctype属性:

image

修改完属性之后,使用request.POST可以获取到文件吗?
很遗憾,还是不能:由于上传文件这个操作确实比较特殊,所以django使用另外的方法进行接受!
使用request.FILES方法接受文件:

image

字典的键('file')由前端的name属性值决定 文件是二进制流的形式暂存于内存
request.FILES也有两种取值方法:
request.FILES.getrequest.FILES.getlist
可以应对单文件和多文件的情况。使用方法和之前类似。

得到的文件对象也支持for循环:

image

注意:可以导入django settings的BASE_DIR设置文件的存放在项目的哪个位置

补充一下,文件对象的方法:file_obj.chunk( )也是一次写一行

image

视图层之FBV与CBV

FBV
	基于函数的视图
	def index(request):return HttpResponse对象

CBV
	基于类的视图
	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())
	会自动根据请求方法的不同自动匹配对应的方法并执行

基于类的视图(CBV):

image

特点: 浏览器发送get请求会自动执行类中的get函数
使用CBV时路由的写法也有点不一样:

image

CBV源码剖析(重要)

1.从CBV的路由匹配切入

path('login/', views.MyLoginView.as_view())
    1.类名点名字(名字的查找问题)
    2.类名点名字并加括号调用(静态方法、绑定给类的方法)

myloginview是我们定义的视图类,其中有getpost两个方法。
所以我们先从myloginview类中找as_view这个名字,我们定义的类里显然没有,所以往父类找(views.View)。
因为是在类中调用as_view(),所以初步判断as_view()应该是个 类方法 或者 是个静态函数

结果真找到了:

image

这里classonlymethod相当于classmethod
先整体浏览源码:

image

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

2.函数名加括号执行优先级最高 项目一启动就会自动执行as_view方法

所以我们的path('login/', views.MyLoginView.as_view())
相当于path('login/', views.view)
得出结论,CBV路由本质还是FBV

3.浏览器地址栏访问login路由需要执行view函数

  1. 产生我们自己编写类的对象
    浏览器访问路由,会执行内层函数view(自动加括号调用)。也就是通过view类产生一个对象。
    查看view函数源码:

image

这里的cls是我们自己创的视图类。view的外层函数是as_wiew。as_wiew是个类方法。我们通过类调用会将类本身作为第一参数传进去也就是这里的cls。

  1. 对象调用dispatch方法(注意查找顺序)

image

此时别的东西都不是核心,先看这个dispatch方法。
请问这个self是什么?

image

  1. self是由我们的视图类产生的对象。此时对象点名字,应该依据名字的查找顺序,一层层查看:
    先查看对象自己 ---> 在查看产生对象的类 ---> 再查看父类
    因为我们自己的类里面没有dispatch 所以这里会调用父类的dispatch

补充:drf就是在我们自己的类里面进行修改(直接拦截 不进行分发):

image

4.研究父类中的dispatch方法

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

我们产生的对象使用父类(View)中的dispatch方法。查看源码:
会先查看我们的请求方法是否属于八个正常的请求方法:

image

点进去看一眼是哪八个:

image

使用反射getatter 通过不同的请求 获取视图类中的方法赋值给handler
此时handler就是我们视图类中的getpost函数

image

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.模板语法的注释前端浏览器是无法查看的 {##}
	模板语法的注释,在模板层就会去掉,而html注释在模板渲染时会保留。
3.django数据获取只能点 jinjia2可以支持get
"""

1.模板语法传值方式 locals

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

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

2.模板语法传值特性

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

总结针对可以加括号调用的名字模板语法都会自动加括号调用(不会自动调用魔法方法)

到底支持哪些东西可以传给模板渲染?
python八大数据类型:

image

模板语法:

image

都可以成功传递:

image

函数可以传吗?

image

类可以传吗?

image

类名传过来之后 会自动加括号 产生一个对象
对象传过来之后 还是对象
image

3.模板语法之过滤器(内置函数)

模板语法给你提供的内置方法 (一些统一的操作方式)
将整数加1:

image

也支持字符串的拼接:
image
add模板方法原理:
image
统计长度:可以对列表、字符串等统计长度
image

切片:对索引1到索引4进行切片
image
节选字符:文件简介的时候可以用,常见的是节选50个字
image
第一个按照你指定的字符截取(第几个字符) 第二个按照空格截取(第几个空格)

格式化时间:需要导入time模块 传入格式化时间
image
单位展示:需要传入一个数字,通常用于显示文件大小。
image
会将这个数字(文件字节数)按照最合适的单位进行展示。

识别html代码:h1这个变量名里面存的是字符串'<p>哈哈哈哈</p>'
image
safe表示安全,表示告知模板语法h1变量名中存储的html代码是安全的。正常情况下,字符串中的html,就会以字符串形式进行展示,而不是作为html。这是因为:
如果在html里面写脚本,脚本里面写死循环呢?
需要告诉django模板层这个东西没有风险。

标签:框架,request,视图,django,虚拟环境,app01,讲解,路由,view
From: https://www.cnblogs.com/oiqwyig/p/16980551.html

相关文章

  • python之路48 django 视图层、模板层
    视图层之必会三板斧用来处理请求的视图函数都必须返回HttpResponse对象完全正确classHttpResponse:passreturnHttpResponse()defrender():returnH......
  • django 视图层
    简介:视图层三板斧详解,JsonResponse对象,request对象获取文件,FBV与CBV,CBV源码剖析目录视图层视图层三板斧详解JsonResponse对象request对象获取文件FBV与CBVFBVCBV源码剖析......
  • django之路由分发,名称空间,虚拟环境,视图层之必备三板斧,JsonResponse对象,视图层之reques
    路由分发应用场景:1、Django的每一个应用都可以有自己的templates文件夹,urls.py、static文件夹,正是基于这个特点,Django能够非常好的做到分组开发(每个人只写自己的app),公......
  • django之视图层
    目录视图层之必会三板斧JsonResponse对象视图层之request对象获取文件视图层之FBV与CBVCBV源码剖析(重要)视图层之必会三板斧用来处理请求的视图函数都必须返回HttpRespo......
  • django之模板层
    模板层模板层的两种语法:"""{{}}:主要与数据值相关{%%}:主要与逻辑相关django的模板语法是自己写的与jinja2不一样1.针对需要加括号调用的名字,django模板语法会自......
  • Djangoday之试图层和模板层
    目录Django之视图层及模板层一、路由分发二、名称空间三、虚拟环境四、试图层之必会三板斧五、视图层之JsonRespnse对象六、视图层之request对象获取文件七、视图层之FBV与......
  • 【Go系列】集成RabbitMQ和Micro框架
    packagemmicroimport("encoding/json""fmt""github.com/go-micro/plugins/v4/broker/rabbitmq""go-micro.dev/v4""go-micro.dev/v4/broker"......
  • 内容类型框架-ContentType 模型
     参考Django官方文档ContentTypeManager¶classContentTypeManager¶ContentType还有一个自定义管理器,ContentTypeManager,它增加了以下方法:clear_cache()¶清除C......
  • rate-limit 一款 java 开源渐进式分布式限流框架使用介绍
    项目简介rate-limit是一个为java设计的渐进式限流工具。目的是为了深入学习和使用限流,后续将会持续迭代。特性渐进式实现支持独立于spring使用支持整合sp......
  • Django之路由层
    django请求生命周期流程图django的生命周期是从用户发送HTTP请求数据到网站响应的过程。整个过程的流程包括:浏览器发送HTTP请求——>wsgiref服务——>中间件—......