目录
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对象
给浏览器返回一个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:以后写代码很多时候可能需要参考源码及所学知识扩展功能
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
基于函数的视图
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()
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源码
更多:https://www.cnblogs.com/Dominic-Ji/articles/10982302.html
手机扫一扫
移动阅读更方便
你可能感兴趣的文章