Django的urls(路由)

Django的urls(路由)

urls.py本质上就是一个标准的python文件

这个python文件的作用就是在URL请求和处理该请求的视图函数之间建立一个对应关系

换句话说,它就是一个url请求映射表。

urls.py基本配置格式:

from django.conf.urls import url

# 由一条条映射关系组成的urlpatterns这个列表称之为路由表
urlpatterns = [
url(regex正则表达式, views视图函数,参数kwatgs=None,别名name=None),   #url本质就是一个函数
]

参数说明

  • regex正则表达式:正则表达式,用来匹配url地址的路径部分,表示视图前缀,视图前缀可以为空
  • views视图:一个可调用对象,通常为一个视图函数,用来处理业务逻辑
  • 参数kwatgs:可选的要传递给视图函数的默认参数(字典形式)(可用在有名分组)
  • 别名name:一个可选的name参数(可用在反向解析)

django 2.0版本的路由系统

2.0版本中re_path和1.11版本的url是一样的用法

from django.urls import path,re_path
urlpatterns = [
path('articles/2003/', views.special_case_2003),
]

正则表达式详解

基本配置

from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

注意事项:

  1. urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
  2. 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
  3. 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
  4. 每个正则表达式前面的'r' 是可选的但是建议加上。

补充说明:

  1. 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项:APPEND_SLASH=True
  2. Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True/False,其作用就是自动在网址结尾加'/'

路由匹配(分组匹配)

分组:就是给一段正则表达式加括号

在Python的正则表达式中,分组命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。

无名分组

在路由匹配的时候,给某段正则表达式加了括号

匹配的时候会将括号内正则表达式匹配到的内容当 做位置参数传递给对应的视图函数

urls.py路由

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

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    
    # 下述正则表达式会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以位置参数的形式传给视图函数,有几个分组就传几个位置参数
    url(r'^aritcle/(d+)/$',views.article), 
]

views.py视图函数

from django.shortcuts import render, HttpResponse

# 需要额外增加一个形参用于接收传递过来的分组数据
def article(request,article_id):
    return HttpResponse('id为 %s 的文章内容...' %article_id)

测试:

在浏览器输入:http://127.0.0.1:8001/article/3/ 会看到: id为 3 的文章内容...

有名分组

给一段正则表达式起一个别名

匹配的时候会将括号内的正则表达式的内容,当作关键字参数传给对应的视图函数

urls.py路由

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

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    
    # 该正则会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以关键字参数(article_id=匹配成功的数字)的形式传给视图函数,有几个有名分组就会传几个关键字参数
    url(r'^aritcle/(?P<article_id>d+)/$',views.article), 
]

views.py视图函数

from django.shortcuts import render, HttpResponse

# 需要额外增加一个形参,形参名必须为article_id
def article(request,article_id):
    return HttpResponse('id为 %s 的文章内容...' %article_id)

测试:

在浏览器输入:http://127.0.0.1:8001/article/3/ 会看到: id为 3 的文章内容...

总结:有名分组和无名分组都是为了获取路径中的参数,并传递给视图函数,区别在于无名分组是以位置参数的形式传递,有名分组是以关键字参数的形式传递。

补充:

无名分组和有名分组不能混合使用

虽然不能混合使用 但是同一种命名方式 可以使用多个

反向解析

通过别名获取路径的过程称为反向解析

在软件开发初期,url地址的路径设计可能并不完美,后期需要进行调整,如果项目中很多地方使用了该路径,一旦该路径发生变化,就意味着所有使用该路径的地方都需要进行修改,这是一个非常繁琐的操作。

试想一个场景,你有200多个a标签,href都指向index/,

有一天在urls里面index改为了new_index,那么你只能手动改变a标签中的href

当你改完,又变成了my_index,那么一天的时间都可能在改地址,那么有没有什么方法,不再把程序写死,反向解析就是应用于此。

解决方案就是在编写一条url(regex, view, kwargs=None, name=None)时

可以通过参数name为url地址的路径部分起一个别名,项目中就可以通过别名来获取这个路径

以后无论路径如何变化别名与路径始终保持一致。

使用方式:

先给路由与视图函数对应关系起一个名字

在urls.py文件中

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    
    url(r'^login/$', views.login,name='login_page'), # 路径login/的别名为login_page
    url(r'^index/$', views.index,name='index_page'), # 路径index/的别名为index_page
]

前端解析

login.html

<!--强调:login_page必须加引号-->
<form action="{% url 'login_page' %}" method="post">

后端解析

在views.py中

from django.shortcuts import render 
from django.shortcuts import reverse # 用于反向解析
from django.shortcuts import redirect #用于重定向页面

url = reverse('index_page')  # reverse会将别名'index_page'反向解析成路径:/index/    

测试:

# 在浏览器输入:http://127.0.0.1:8001/login/ 会看到登录页面,输入正确的用户名密码会跳转到index.html
# 当我们修改路由表中匹配路径的正则表达式时,程序其余部分均无需修改

总结:

在views.py中,反向解析的使用:
    url = reverse('index_page')
在模版login.html文件中,反向解析的使用
    {% url 'login_page' %}

无名分组反向解析

url(r'^aritcle/(d+)/$',views.article,name='article_page'), # 无名分组

前端解析

{% url 'article_page' 1 %}

后端解析

url = reverse('article_page',args=(1,)) 

有名分组反向解析

url(r'^user/(?P<uid>d+)/$',views.article,name='user_page'), # 有名分组

前端解析

{% url 'user_page' 1 %} # 推荐使用
{% url 'user_page' uid=1 %}# 标准的

后端解析

url = reverse('user_page',args=(1,))
url = reverse('user_page',kwargs={'uid':1}) 

路由分发

当django项目比较庞大的时候,路由与视图函数对应关系较多

总路由代码太多冗长

考虑到总路由代码不好维护, django支持每个app都可以有自己的urls.py

并且总路由不再做路由与视图函数的对应关系,而仅仅只做一个分发任务的操作

根据请求的不同 识别出当前请求需要访问的功能属于哪个app然后自动

下发到对应app里面的urls.py中 然后由app里面的urls.py做路由与视图函数的匹配

不仅如此每个app除了可以有自己的urls.py之外 还可以有自己的static文件夹 templates模板文件

基于上面的特点,基于django分小组开发 会变得额外的简单

每个人只需要开发自己的app即可 之后只需要创建一个空的django项目

将多个人的app全部拷贝项目下 配置文件注册

总路由分发一次

需要一个分发的模块

from django.conf.urls import url,include

url(r'^app01/',include('app01.urls')),

url(r'^app02/',include('app02.urls'))

子路由

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

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

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

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

名称空间

url(r'^app01/',include('app01.urls',namespace='app01'))
url(r'^app02/',include('app02.urls',namespace='app02'))
后端解析
reverse('app01:index')
reverse('app02:index')
前端解析
{% url 'app01:index' %}
{% url 'app02:index' %}
# 在给路由与视图函数起别名的时候只需要保证永远不出现冲突的情况即可
# 通常情况下我们推荐期别名的时候加上当前应用的应用名前缀

url(r'^index/',views.index,name='app01_index')
url(r'^index/',views.index,name='app02_index')

虚拟环境

我们想做到针对不同的项目 只安装项目所需要的功能模块

项目用不到的一概不装 来避免加载资源时的消耗

如何创建虚拟环境

虚拟环境就类似于一个纯净的python解释器环境

大白话 每创建一个虚拟环境就类似于你重新下载一个python解释器

虚拟环境不推荐你使用太多

学习阶段我们还是用本机的环境即可 将所有模块全部装到本机环境下

伪静态

url以.html结尾 给人的感觉好像是这个文件是写死的 内容不会轻易的改变

为了提高你的网站被搜索引擎收藏的力度 提供网站的SEO查询效率

原文地址:https://www.cnblogs.com/kai-/p/12158918.html