64、django详讲之--生命周期

文章目录

  • 一、django生命周期流程图
  • 二、路由层
    • 2.1 路由匹配
    • 2.2 无名分组
    • 2.3 有名分组
    • 2.4 无名分组与有名分组不可以混合使用
    • 2.5 反向解析
    • 2.6 无名分组有名分组的反向解析
      • 2.6.1 无名分组的反向解析
      • 2.6.2 有名分组的反向解析
    • 2.7 路由分发
    • 2.8 名称空间
    • 2.9 伪静态(了解)
  • django版本区别
    • 2.10 JsonResponse对象
    • 2.11 form 表单上传文件
    • 2.12 request 对象方法补充
    • 2.13 FBV与CBV
  • 三、模板层
  • 四、

一、django生命周期流程图

64、django详讲之--生命周期_第1张图片

  • 图说明
    • 缓存数据库

      • 提前已经将你想要的数据准备好, 可以直接拿走
      • 提高效率和响应时间
    • 红色箭头为正常走向

    • 绿色箭头为缓存判断, 如果没有, 走红色箭头回来的时候走黄色箭头, 存到缓存中一份, 下次就可以用了

二、路由层

2.1 路由匹配

# 路由匹配
url(r'test', views.test),
url(r'testadd', views.test),
'''
url方法第一个参数是正则表达式
	只要第一个参数正则表达式能够匹配到内容  那么就会立刻停止往下匹配, 直接执行对应的视图函数

你在输入url的时候会默认加斜杠
	django内部帮你做到重定向
	一次匹配不行
	url加斜杠再来一次
'''
# 取消自动加斜杠
APPEND_SLASH = False/True  # 默认是自动加斜杠的

urlpatterns = [
    # 首页
    url(r'^$', views2.home),
    # 路由匹配
    url(r'^test/$', views2.test),
    url(r'^testadd/$', views2.testadd),
]

2.2 无名分组

# 分组: 就是给某一段正则表达式用小括号括起来
url(r'^test/(\d+)/', view.test)

def test(request, xx):
	print(xx)
	return HttpResponse('test')

# 无名分组就是将括号内的正则表达式匹配到的内容当作位置参数传递给后面的视图函数

2.3 有名分组

# 可以给正则表达式起一个别名

url(r'testadd/(?P\d+)', view.testadd)

def test(request, year):
	print(year)
	return HttpResponse('testadd')

# 有名分组就是将括号内的正则表达式匹配到的内容当作关键字参数传递给后面的视图函数

2.4 无名分组与有名分组不可以混合使用

# 但是同一个分组可以使用n多次
# 单个的分组可以使用多次
url(r'^index/(\d+)/(\d+)/(\d+)/', views2.index),
url(r'^index/(?P\d+)/(?P\d+)/(?P\d+)/', views2.index),

2.5 反向解析

# 通过一些方法得到一个结果, 该结果就可以直接访问对应的url触发视图函数

# 先给路由函数起一个别名
url(r'^func_k/', views.func, name='bieming')

# 反向解析
	# 后端反向解析
	from django.shortcuts import render, HttpResponse, redirect, reverse
	reverse('别名')
	
	# 前端反向解析
	<a href="{% url 'bieming' %}"></a>

2.6 无名分组有名分组的反向解析

2.6.1 无名分组的反向解析

  • urls.py
urlpatterns = [
    url(r'^index/(\d+)', views.index, name='xxx'),
]
  • views.py (后端)
from django.shortcuts import render, HttpResponse, reverse


# Create your views here.

def index(request, age):
    print(reverse('xxx', args=(age,)))
    print(age)
    # print(reverse('xxx'))
    # return render(request, 'index.html')
    return HttpResponse('无名分组的反向解析')
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="">{% url 'xxx'  123 %}</a>
</body>
</html>
  • 访问方式: index/数字
  • 这个数字写代码的时候应该放什么呢
  • 数字一般情况下放的是数据的主键值

2.6.2 有名分组的反向解析

  • 简写
# 有名分组的反向解析
url(r'^index_you/(?P\d+)', views.index_you, name='ooo'),

# 后端
	# 有名分组的反向解析 写法一: 了解
    print(reverse('ooo', kwargs={'year': 123}))
    # 写法二: 简单写法
    print(reverse('ooo', args=(year,)))
# 前端
	<a href="">{% url 'xxx'  year=123 %}</a>
	<a href="">{% url 'xxx'  123 %}</a>

# 访问方法同无名分组

2.7 路由分发

django的每一个应用都可以由自己的templates文件夹, urls.py, static文件夹, 正是基于上述的特点, django能够非常好的的做到分组开发(每个人只写自己的app, 再将每一个app拷贝到一个新的django项目中, 然后再配置文件里面注册, 所有的app再利用路由分发的特点, 将所有app整合

当一个django项目中的url特别多的时候, 总路由urls.py的代码非常冗余, 不好维护, 这个时候可以利用路由分发来减轻总路由的压力

利用路由分发以后, 总路由不再是路由与视图函数的对应关系, 而是做一个分发处理
	识别当前url是哪个应用下的, 直接分发给对应的应用去处理
  • 总路由urls.py
from app01 import urls as app01_urls
from app02 import urls as app02_urls

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    # 1、路由分发
    # url(r'^app01/', include(app01_urls)),  # 只要url前缀是app01开头的, 全部交给app01处理
    # url(r'^app02/', include(app02_urls))  # 只要url前缀是app02开头的, 全部交给app01处理

    # 2、终极写法, 推荐使用,
    # url(r'^app01/', include('app01.urls', namespace='app01')),
    # url(r'^app02/', include('app02.urls', namespace='app02')),
    url(r'^app01/', include('app01.urls', )),
    url(r'^app02/', include('app02.urls', )),
    # 注: 千万不能加$结尾
]
  • 子路由app01 urls.py
from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r'^index/', views.index, name='index'),
]

  • 子路由app02 urls.py
from django.conf.urls import url
from app02 import views

# 伪静态页面
urlpatterns = [
    url(r'^index.html', views.index, name='index'),
]

2.8 名称空间

  • 其实只要保证名字不冲突, 就没有必要使用名称空间
# 名称空间
# 总路由
url(r'^app01/', include('app01.urls', namespace='app01')),
url(r'^app02/', include('app02.urls', namespace='app02')),

# 解析的时候
# app01
urlpatterns = [
    url(r'^index/', views.index, name='index'),
]

# app02
urlpatterns = [
    url(r'^index/', views.index, name='index'),
]

reverse('app01:index')
reverse('app02:index')

{% url 'app01:reg' %}
{% url 'app02:reg' %}
  • 一般情况下, 有多个app的时候我们再起别名的时候就会加上app的前缀,这样的话就能确保多个app之间名字不冲突的问题
  • 像这样
urlpatterns = [
    url(r'^index/', views.index, name='app01_index'),
]

urlpatterns = [
    url(r'^index/', views.index, name='app02_index'),
]

2.9 伪静态(了解)

静态页面
	数据是写死的  万年不变

伪静态:
	将一个动态网页伪装成静态网页

	为什么要伪装?
		伪装的目的在于增大本网站的seo查询力度
		并且增加搜索引擎收藏本网站的概率
		
	搜索引擎其实就是一个巨大的爬虫程序
	
	总结:
		无论你怎么优化  怎么处理
		始终还是干不过RMB玩家

django版本区别

1、django1.x 路由层使用的是url方法, 而django2.x/3.x版本中路由层使用的是path方法,
url: 第一个参数支持正则
path: 第一个参数不支持正则, 写什么匹配什么

但是2.x/3.x中提供了
from django.urls import path, re_path
re_path(r'^index/', inedx)
# 2.x/3.x中的re_path就等价于1.x里面的url

2、虽然path不支持正则, 但是他的内部支持五种转换
path('index//', index)
# 将第二个路由里面的内容先转换成整形以后以关键字的形式传递给后买你的视图函数

def index(request, id):
	print(id, type(id))
	return HttpResponse('index')

str: 匹配除了路径分隔符(/)之外的非空字符串, 这是默认的形式
intint匹配正整数, 包含0
slug: 匹配字母、数字、横杠、下划线组成的字符串
uuid: 匹配格式话的uuid, 如: 07545-44
path: 匹配任何非空字符串, 包含了路径分隔符(/3、除了默认的五个转换器以外, 还支持自定义转换器(了解)

class MonthConverter:
	regex='\d{2}'  # 属性名必须是regex
	
	def to_python(self,value):
		return int(value)
	
	def to_url(self, value):
		return value  # 匹配的regex是两个数字, 返回的结果也必须是两个数字

from django.urls import path.register_converter
from app01.register_converter import MonthConverter

# 先注册转化器
from app01 import views

urlpatterns = [
    path('index///', views.index, name='ooo'),
]

4、模型层里面1.x外键默认是级联更新删除的, 但是2.x/3.x中需要你自己手动配置参数
models.ForeignKey(to='Publish')

models.ForeignKey(to='Publish', on_delete=models.CASCADE...)

2.10 JsonResponse对象

'''
json格式的数据有什么用?
	前后端数据交互需要使用到json作为过渡,实现跨语言传输数据
'''
import json
from django.http import JsonResponse

# 不用JsonResponse 返回json格式
def ab_json(request):
	user_dict = {'username': 'zpp酷''age':18}
	# 先转化成json格式字符串
	json_str= json.dumps(user_dict, ensure_ascii=False)
	# 将该字符串返回
	return HttpResponse(json_str)
	
	
# 看JsonResponse 源码, 掌握用法
def ab_json(request):
	user_dict = {'username': 'zpp酷''age':18}
	return HttpResponse(user_dict, json_dumps_params={'ensure_ascii': False})

# 默认只能序列化字典, 其他需要加safe参数
return HttpResponse(l_list, safe=False)

2.11 form 表单上传文件

'''
form 表单上传文件类型的数据
	1、method 必须指定成post
	2、enctype 必须换成formdata
'''
def ab_file(request):
	if request.method == 'post':
		# print(request.POST)  # 只能获取普通的键值对数据, 文件不行
		print(request.FILES)  # 获取文件数据
		file_obj = request.FILES.get('file')  # 文件对象
		print(file_obj.name)
		with open(file_obj.name, 'wb') as f:
			for line in file_obj.chunks():
				f.write(line)
	return render(request, 'form.html')

2.12 request 对象方法补充

'''
request.method
request.POST
request.GET
request.FILES
request.body # 原生的浏览器发过来的二进制数据
request.path
request.path_info
request.get_full_path()  # 能够获取完整的url及问号后面的参数
'''

print(request.path) # /app01/ab_file/
print(request.path_info) # /app01/ab_file/
print(request.get_full_path()) # /app01/ab_file/?username=zpp

2.13 FBV与CBV

# 视图
# FBV: 视图函数是函数
def index(request):
	return HttpResponse('index')

# CBV: 视图函数是类
# 路由
url(r'login/', view.MyLogin.as_view())

from django.views import View
class MyLogin(View):
	def get(self.request):
		return render(request, 'form.html')
	
	def post(self.request):
		return HttpResponse('post方法')
'''
FBV和CBV各有千秋
CBV特点:
	能够直接根据请求方式的不同直接匹配到对应的方法执行
'''

三、模板层

四、

相关连接(笔记来自于视频课程的归类整理):
[1]: https://www.bilibili.com/video/BV1QE41147hU?p=17
[2]: https://www.cnblogs.com/Dominic-Ji/p/11093137.html
[3]: https://zhuanlan.zhihu.com/p/114200361
[4]: https://www.cnblogs.com/xiaoyuanqujing
[5]:https://www.cnblogs.com/liuqingzheng/articles/9506212.html

你可能感兴趣的:(python全栈学习分享,django,python)