跳至内容

Django路由层

路由层(URLconf)是 Django 中 URL 与视图函数的映射配置。本文介绍路由的定义方式、正则匹配规则、有名/无名分组、反向解析、路由分发(include),以及 Django 2.x 新增的 pathre_path 用法。

路由层

1、什么是路由

	路由即请求地址与视图函数的映射关系

2、路由配置

	from django.conf.urls import url
    from django.contrib import admin
    from app01 import views

    urlpatterns = [
		url(正则表达式, views视图函数参数别名),
    ]
        正则表达式一个正则表达式字符串
        views视图函数一个可调用对象通常为一个视图函数或一个指定视图函数路径的字符串
        参数可选的要传递给视图函数的默认参数字典形式
        别名一个可选的name参数
        
正则表达式
    1urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式一旦匹配成功则不再继续
    2若要从URL中捕获一个值只需要在它周围放置一对圆括号分组匹配)。
    3不需要添加一个前导的反斜杠因为每个URL 都有例如应该是^articles 而不是 ^/articles
    4每个正则表达式前面的'r' 是可选的但是建议加上
	在Djangosettings.py配置文件中有一个参数可以控制是否自动在网址结尾加/
		APPEND_SLASH=True   默认是开启的
        
	
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        # 首页
        url(r'^$',views.home),
        # 路由匹配
        url(r'^test/$',views.test),
        url(r'^testadd/$',views.testadd),
        # 尾页(了解)
        url(r'',views.error),
    ]

3、分组

什么是分组
	简单来说分组就是给某一段正则表达式用小括号括起来可以分为有名分组和无名分组
    
无名分组
	无名分组就是将括号内正则表达式匹配到的内容当作位置参数传递给后面的视图函数
        urlpatterns = [
            url(r'^admin/', 
                admin.site.urls),

            # 下述正则表达式会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以位置参数的形式传给视图函数,有几个分组就传几个位置参数
            url(r'^aritcle/(\d+)/$',views.article), 
        ]
    此外在views.py文件中需要额外增加一个形参用于接收传递过来的分组数据
        def article(request,article_id):
            return HttpResponse('id为 %s 的文章内容...' %article_id)
            
有名分组
	有名分组就是将括号内正则表达式匹配到的内容当作关键字参数传递给后面的视图函数
        urlpatterns = [
            url(r'^admin/', admin.site.urls),

            # 该正则会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以关键字参数(article_id=匹配成功的数字)的形式传给视图函数,有几个有名分组就会传几个关键字参数
            url(r'^aritcle/(?P<article_id>\d+)/$',views.article), 
        ]
	此外在views.py中需要增加一个形参形参名必须是urls.py中指定的名字
        形参名必须为article_id
        def article(request,article_id):
            return HttpResponse('id为 %s 的文章内容...' %article_id)

有名分组和无名分组的区别
	有名分组和无名分组都是为了获取路径中的参数并传递给视图函数区别在于无名分组是以位置参数的形式传递有名分组是以关键字参数的形式传递
	有名分组和无名分组不可以混合使用但是同一种分组可以多次使用

    	

4、反向解析

什么是反向解析
	通过一些方法得到一个结果该结果可以直接访问对应的url触发视图函数
    
配置反向解析:
	先给路由与视图函数起一个别名
		url(r'^func_kkk/',views.func,name='ooo')
	后端反向解析
		from django.shortcuts import render,HttpResponse,redirect,reverse
  			reverse('ooo')
  	前端反向解析
  		<a href="{% url 'ooo' %}">111</a>
	注意起的别名不可以出现重复
	
有名分组与无名分组的反向解析
	无名分组反向解析
		url(r'^index/(\d+)/',views.index,name='xxx')
		前端{% url 'xxx' 123 %}
		后端reverse('xxx', args=(1,))
        
	有名分组反向解析
		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>  		方法二
        后端
        	reverse('ooo',kwargs={'year':123})          方法一
 			reverse('ooo',args=(111,))					方法二
后端使用反向解析的时候需要先导入模块
	from django.shortcuts import reverse

5、路由分发

	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.路由分发
            url(r'^app01/',include(app01_urls)),  # 只要url前缀是app01开头 全部交给app01处理
            url(r'^app02/',include(app02_urls))   # 只要url前缀是app02开头 全部交给app02处理

            # 2.终极写法  推荐使用
            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)
        ]
        

6、名称空间

什么是名称空间
	当多个应用出现了相同别名的时候反向解析没有办法自动识别前缀所以在配置的时候可以直接指定名称空间
    # 总路由
        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')
    ]

7、伪静态

	将一个动态网页伪装成静态网页
	伪装的目的在于增大网站的seo查询力度
	但是无论怎么优化都不如RMB玩家
        urlpatterns = [
            url(r'^reg.html',views.reg,name='app02_reg')
        ]

8、虚拟环境

在正常开发中 我们会给每一个项目配备一个该项目独有的解释器环境
该环境内只有该项目用到的模块 用不到一概不装

linux缺什么才装什么

虚拟环境
	你每创建一个虚拟环境就类似于重新下载了一个纯净的python解释器
	但是虚拟环境不要创建太多是需要消耗硬盘空间的

扩展:
	每一个项目都需要用到很多模块 并且每个模块版本可能还不一样
	那我该如何安装呢 一个个看一个个装???
	
	开发当中我们会给每一个项目配备一个requirements.txt文件
	里面书写了该项目所有的模块即版本
	你只需要直接输入一条命令即可一键安装所有模块即版本
	
最后更新于