django03--请求生命周期、路由层

一 django请求生命周期流程图(必会)

# 每个人都要会画 这个图是你们后期复习django最好的一个梳理方式

1.用户在浏览器中输入url,发送一个GET方法的request请求。
2.Django中封装了socket的WSGi服务器,监听端口接受这个request 请求,再进行初步封装,然后传送到中间键中
3.中间件,对请求进行校验或处理
4.传输到路由系统中进行路由分发,匹配相对应的视图函数(FBV)
5.视图函数中,进行业务逻辑的处理,
6.调用modles中表对象,通过orm拿到数据库(DB)的数据。同时拿到templates中相应的模板进行渲染,
7.然后将这个封装了模板response响应传输到中间键中,依次进行处理
8.最后通过WSGi再进行封装处理,响应给浏览器展示给用户


# 扩展知识点
  缓存数据库
    提前已经将你想要的数据准备好了 你来直接拿就可以
    提高效率和响应时间
		
  当你在修改你的数据的时候 你会发现数据并不是立刻修改完成的
  而是需要经过一段时间才会修改

二 路由层

1 路由匹配

# 路由匹配
  路由: 即请求地址与视图函数的映射关系
      
# 基本格式
from django.conf.urls import url

urlpatterns = [
     url(正则表达式, views视图函数,参数,别名),
]

# 参数说明
  正则表达式:一个正则表达式字符串
  views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
  参数:可选的要传递给视图函数的默认参数(字典形式)
  别名:一个可选的name参数

# 匹配原则
  从上往下 正则表达式能够匹配到内容,就算匹配成功 
  会立刻执行后面的视图函数,并且结束整个路由匹配过程
    
    
# 注意:
你在输入url的时候会默认加斜杠
  django内部帮你做到重定向
     第一次匹配不行
     url后面加斜杠再来一次


# 取消自动加斜杠 (setting.py)
APPEND_SLASH = False/True	# 默认为True 是自动加斜杠的 



# eg:
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 首页
    url(r'^$',views.home),
    # 路由匹配
    url(r'^test/$',views.test),
    url(r'^testadd/$',views.testadd),
    
    # 尾页(404页面)   放在路由匹配最下面,上面所有路径都匹配不到,会走这个
    url(r'',views.error),
]

2 路由分组

分组:就是将路由层的某一段正则表达式用小括号扩起来,表示匹配到的内容是一个整体

2.1 无名分组

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

url(r'^test/(\d+)/',views.test)

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

2.2 有名分组

# 有名分组   将括起来的正则表达式 起一个别名
  就是将路由层括号内正则表达式匹配到的内容
  当作 关键字参数 传递给对应的视图函数


url(r'^testadd/(?P<year>\d+)',views.testadd)

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

2.3 无名有名能否混用

# 无名有名分组 不能混用
  但是同一种分组可以使用N多次

# 单个分组情况下,可以重复使用
url(r'^index/(\d+)/(\d+)/(\d+)/', views.index),
url(r'^index1/(?P<year>\d+)/(?P<month>\d+)/(?P<day>\d+)/', views.index1),

def index(request,*args,**kwargs):
    print(args)
    return HttpResponse('test')

def index1(request,*args,**kwargs):
    print(kwargs)
    return HttpResponse('test')

3 反向解析

3.1 普通反向解析

反向解析:通过一些方法得到一个结果,该结果可以直接访问对应的url ,从而触发视图函数

# 简单理解:
  给路由匹配取一个别名,通过别名的反向解析,能获取到对应的url,从而触发执行视图函数


# 在路由层书写路由与视图函数时,起一个别名
    url('home/', views.home,name='home'),
    
# 反向解析   
  # 后端反向解析(需要导入reverse模块)  	
    from django.shortcuts import render,HttpResponse,redirect,reverse
    def home(request):
        print(reverse('home'))   # '/home/'
        return render(request, 'home.html')
            
  # 前端反向解析
    <a href="{% url 'home'%}">111</a>   # href='/home/'

3.2 无名分组反向解析

# 作用
  通过反向解析的方式,将url分组匹配到的内容,当做位置参数,传递给视图函数,并触发执行

# 无名分组反向解析
    url(r'^index/(\d+)/',views.index,name='xxx')
	
# 需要制定正则表达式匹配的参数
# 前端
    {% url 'xxx' 123 %}   # /index/123
    
# 后端
    reverse('xxx', args=(1,))   # 注意是元祖的形式

    
# 注意:
这个数字写代码的时候应该放什么?
  数字一般情况下放的是数据的主键值  数据的编辑和删除
    
    url(r'^edit/(\d+)/',views.edit,name='xxx')
	
    def edit(request,edit_id):
        reverse('xxx',args=(edit_id,))
		
    {%for user_obj in user_queryset%}
        <a href="{% url 'xxx' user_obj.id %}">编辑</a>
    {%endfor%}

3.3 有名分组反向解析

# 有名分组反向解析
   url(r'^func/(?P<year>\d+)/',views.func,name='ooo')
    
# 前端
    <a href="{% url 'ooo' year=123 %}">111</a>  了解
    <a href="{% url 'ooo' 123 %}">222</a>  	记忆  简写

# 后端	
   # 有名分组反向解析 写法1  了解
   print(reverse('ooo',kwargs={'year':123}))

   # 简便的写法  减少你的脑容量消耗 记跟无名一样的操作即可
   print(reverse('ooo',args=(111,)))


# 总结:
  有名/无名分组方向解析,只是路由层不同,反向解析时,统一记无名的形式即可

4 路由分发

"""
django的每一个应用都可以有自己的
  templates文件夹 
  urls.py 
  static文件夹
  
也就意味着多人协同开发变得更加的简单了
"""

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

  利用路由分发之后 总路由不再干路由与视图函数的直接对应关系
  而是做一个分发处理
    识别当前url是属于哪个应用下的 直接分发给对应的应用去处理
	


# 总路由
from app01 import urls as app01_urls
from app02 import urls as app02_urls

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 1.路由分发  (需要导入app01和app02模块)
    url(r'^app01/',include(app01_urls)),  # 只要url前缀是app01开头 全部交给app01处理
    url(r'^app02/',include(app02_urls))   # 只要url前缀是app02开头 全部交给app02处理
  
    # 2.终极写法  推荐使用  (以字符串的形式,就不用导入app01和app02模块)
    url(r'^app01/',include('app01.urls')),
    url(r'^app02/',include('app02.urls'))
    # 注意事项:总路由里面的url千万不能加$结尾
]


# 子路由
  # app01 urls.py
  from django.conf.urls import url
  from app01 import views

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

  # app02 urls.py
  from django.conf.urls import url
  from app02 import views

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

5 名称空间(了解)

# 当多个应用出现了相同的别名 我们研究反向解析会不会自动识别应用前缀?
  正常情况下的反向解析是没有办法自动识别前缀的,
  需自己带上名称空间,表明是哪个应用的


# 名称空间
    # 总路由
    url(r'^app01/',include('app01.urls',namespace='app01')),
    url(r'^app02/',include('app02.urls',namespace='app02'))
    # 解析的时候
    # app01
    urlpatterns = [url(r'^reg/',views.reg,name='reg')]
    
    # app02
    urlpatterns = [url(r'^reg/',views.reg,name='reg')]
    
    reverse('app01:reg')
    reverse('app02:reg')
    
    {% url 'app01:reg' %}
    {% url 'app02:reg' %}
    
# 其实只要保证名字不冲突 就没有必要使用名称空间
  一般情况下 有多个app的时候我们在起别名的时候会加上app的前缀
  这样的话就能够确保多个app之间名字不冲突的问题

urlpatterns = [
    url(r'^reg/',views.reg,name='app01_reg')
]
urlpatterns = [
    url(r'^reg/',views.reg,name='app02_reg')
]

6 伪静态(了解)

# 静态网页
  数据是写死的 万年不变
	
# 伪静态
  将一个动态网页伪装成静态网页
	
# 为什么要伪装呢?
  https://www.cnblogs.com/Dominic-Ji/p/9234099.html
  伪装的目的在于增大本网站的seo查询力度
  并且增加搜索引擎收藏本网上的概率
	
  搜索引擎本质上就是一个巨大的爬虫程序
	
  总结:
    无论你怎么优化 怎么处理
    始终还是干不过RMB玩家


# 正则加上 .html 后缀
urlpatterns = [
    url(r'^reg.html',views.reg,name='app02_reg')
]

三 虚拟环境(了解)

# 虚拟环境
  1.能够实现针对不同的项目配备专属的编程环境
    该环境内只有该项目用到的模块 用不到一概不装
  2.创建一个虚拟环境,就类似于重新下载了一个纯净的python解释器
    但是虚拟环境不要创建太多,是需要消耗硬盘空间的
  3.虚拟环境的唯一表示是venv文件夹
	
# pycharm中创建虚拟环境 记得要勾选--可用于所有项目

四 django版本区别

# 1.url方法
  django1.X路由层使用的是url方法
  django2.X和3.X版本中路由层使用的是path方法

  url()  # 第一个参数支持正则
  path() # 第一个参数是不支持正则的 写什么就匹配什么
	
	
  如果你不习惯使用path, 那么也给你提供了另外一个方法
    from django.urls import path, re_path
    re_path(r'^index/',index)
		
    from django.conf.urls import url  # 最好不要使用这种,因为这是1.x的方法
    url(r'^login/',login)
    	
    2.X和3.X里面的re_path <==> 1.X里面的url
 
 
# 2.虽然path不支持正则 但是它的内部支持五种转换器
  path('index/<int:id>/',index)
  # 将第二个路由里面的内容先转成整型,然后以关键字的形式传递给后面的视图函数

  def index(request,id):
      print(id,type(id))
      return HttpResponse('index')
    
  str  # 匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
  int  # 匹配正整数,包含0
  slug # 匹配字母、数字以及横杠、下划线组成的字符串
  uuid # 匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00
  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.path_converts import MonthConverter

# 先注册转换器
register_converter(MonthConverter,'mon')

from app01 import views

urlpatterns = [
    path('articles/<int:year>/<mon:month>/<slug:other>/', 	views.article_detail, name='aaa'),
]


# 4.模型层
  1.X外键默认都是级联更新删除的
  2.X和3.X中需要你自己手动配置参数

  models.ForeignKey(to='Publish')
	
  models.ForeignKey(to='Publish',on_delete=models.CASCADE...)
posted @ 2021-09-10 01:30  Edmond辉仔  阅读(32)  评论(0编辑  收藏  举报