昨日内容回顾
- 数据增删改查可视化界面
1.request对象方法
request.GET\request.POST\request.method
2.数据库迁移命令
makemigrations\migrate
3.form表单提交数据的特征
action参数:三种情况\method参数:两种情况
- django请求生命周期流程图
客户端浏览器
web服务网关接口
django中间件
路由层
视图层
模板层
模型层
数据库
- 路由层之路由匹配
# APPEND_SLASH = True
path('index/',views.index) # 固定死的
index(request对象)
- 路由层之路由转换器
path('index/<str:name>/<int:id>', view.index) # 动态匹配
index(request对象,name='',id='')
默认提供五种转换器并且支持自定义转换器(自己写正则)
- 路由层之正则匹配
re_path('^index/$', views.index) # 固定死的
index(request对象)
- 路由层之无名有名分组
re_path('^index/\d+/.*?/',views.index) # 不分组的情况
index(request对象)
re_path('^index/(\d+)/(.*?)/',views.index) # 无名分组
index(request对象,\d+匹配到的内容,.*?匹配到的内容)
re_path('^index/(?P<year>\d+)/(?P<id>.*?)',views.index) # 有名分组
index(request对象,year='',id='')
- 反向解析
根据一个名字解析出一个结果 该结果可以访问某一个对应的路由
path('index/', views.index, name='index_view')
<a href='/index/'></a>
{% url 'index_view' %} /index/
reverse('index_view') /index/
path('index/<>str:info/', views.index, name='index_view') <a href='/index/jason/'></a>
<a href='/index/kevin/'></a>
{% url 'index_view' 'jason' %} /index/jason/
reverse('index_view',args=('tony',)) /index/tony/
re_path('index/(?P<year>\d+)', views.index, name='index_view')
<a href='/index/1/'></a>
<a href='/index/123/'></a>
{% url 'index_view' '321' %} /index/321/
reverse('index_view', args=('111',)) /index/111/
今日内容概要
- 路由分发
- 名称空间
- 虚拟环境
- 视图层之必会三板斧
- 视图层之JsonResponse对象
- 视图层之request对象获取文件
- 视图层之FBV与CBV
- CBV源码剖析
- 模板层
今日内容详细
路由分发
django支持每个应用都可以有自己独立的路由层、静态文件、模板层。基于该特性多人开发项目就可以完全解耦合,之后利用路由分发还可以整合到一起
多个应用都有很多路由与视图函数的对应关系 这个时候可以拆分到各自的路由层中
使用路由分发之前 总路由直接干路由与视图函数的匹配的活
path('index/',index)
使用路由分发之后 总路由只按照应用名分配匹配方向
path('app01/', include('app01.urls'))
'''应用文件内创建urls.py为子路由的路由层'''
名称空间
路由分发之后 针对相同的别名能否自动反向解析出不同的应用前缀
默认情况下是无法直接识别应用前缀的
如果想要正常识别区分有两种方式:
方式1:名称空间
总路由
path('app01/', include(('app01.urls','app01'), namespace='app01')),
path('app02/', include(('app02.urls', 'app02'), namespace='app02')),
反向解析
reverse('app01:index_view')
reverse('app01:index_view')
方式2:别名不冲突即可 # 推荐使用
多个应用别名不冲突可以用应用名作为别名的前缀
path('index/',view.index, name='app01_index_view')
path('index/',view.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
视图层之必会三板斧
用来处理请求的视图函数都必须返回HttpResponse对象 # 完全正确
class HttpResponse:
pass
return HttpResponse()
def render():
return HttpResponse()
return render()
def redirect():
redirect_class = 类(祖先有个类是HttpResponse)
return redirect_class()
return redirect()
JsonResponse对象
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.dunps(user_dict, ensure_ascii=False)
# return HttpResponse(user_json)
return JsonResponse(user_dict)
# 如果想阻止转码 需要添加参数
return JsonResponse(user_dicy, json_dumps_params={'ensure_ascii': False})
ps:以后写代码很多时候可能需要参考源码及所学知识扩展功能
class JsonResponse():
def __init__(self,data,json_dumps_params=None):
json.dumps(data,**json_dunps_params)
JsonResponse主要序列化字典 针对非字典的其他可以被序列化的数据需要修改safe参数为False
视图层之request对象获取文件
form表单携带文件类型的数据需要做到以下几点
1.method必须是post
2.enctype必须是multipart/form-data
django后端需要通过request.FILES获取文件类型的数据
视图层之FBV与CBV
FBV
基于函数的视图
def index(request):return HttpResponse对象
CBV
基于类的视图
from django import views
class MyLoginView(views.View): # 必须要添加views.View参数
def get(self, request):
return HttpResponse('from CBV get function')
def post(self, request):
return HttpResponse('from CBV post function')
urls文件中:path('login/', views.MyLoginView.as_view())
会自动根据请求方法的不同自动匹配对应的方法并执行
CBV源码剖析(重要)
1.从CBV的路由匹配切入
path('login/', views.MyLoginView.as_view())
1.类名点名字(名字的查找问题)
2.类名点名字并加括号调用(静态方法、绑定给类的方法)
2.函数名加括号执行优先级最高 项目一启动就会自动执行as_view
path('login/',views.view) # CBV路由本质还是FBV
3.浏览器地址栏访问login路由需要执行view函数
1.产生我们自己编写的类的对象
2.对象调用dispatch方法(注意查找顺序)
4.研究父类中的dispatch方法
获取当前请求方法并转小写 之后利用反射获取类中对应的方法并执行
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.模板语法的注释前端浏览器是无法查看的{##}
"""
1.模板语法传值
return render(request, 'demo02.html', {'n1': name, 'a1':age})
# 传值方式1:精准传值 不浪费资源 针对多资源的传递书写麻烦
return render(request, 'demo02.html', locals()) # 传值方式2:将函数名称空间中的所有的名字全部传递 名字过多并且不使用的情况下比较浪费资源
2.模板语法传值特性
1.基本数据类型正常展示
2.文件对象也可以展示并调用方法
3.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)
4.类名也会自动加括号调用
5.对象则不会
ps:总结针对可以加括号调用的名字模板语法都会自动加括号调用
3.模板语法之过滤器(内置函数)
{{i|add:10}} |add: # 自增
{{l|length}} |length # 长度
{{s|slice:'1:4'}} |slice:'' # 切割
{{s|truncatechars:5}} |truncatechars: # 按字符数显示 剩下的用... ...占用一个字符数
{{s|truncatewords:1}} |truncatewords: # 按单词数显示 剩下的用...
{{ctime|date:'Y年-m月-d日 H:i:s'}} # 后端导入datetime.today()模块 html文件中模板语法写入时间模块
{{file_size|filesizeformat }} # 按合适的单位展示字节数大小
{{h1|safe}} # 后端使用前端语法代码传输html模板语法中直接可以执行c前端代码
标签:index,return,request,视图,path,路由,view
From: https://www.cnblogs.com/DragonY/p/16980546.html