Django- url路由控制器

前言html

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行。python

urls.py:  请求路径与视图函数的映射关系正则表达式

 

一:URLconf配置

1.1   基本格式

注意url()是1版本的,path()是2版本的django

 

from django.conf.urls import url

 

urlpatterns = [

     url(正则表达式, views视图,参数,别名),

url(r'^articles/2003/$', views.special_case_2003),    #为何咱们不在函数名后加()呢?由于启动Django的
                      #时候,会把这个文件加载一遍,若是函数名(),那么就会执行这个函数了。 ] 注意:这是版本1的,到版本2 path('articles/2003/', views.special_case_2003) 其实,默认path在正则的位置是封装了^以及$的


参数:
  • 正则表达式:一个正则表达式字符串
  • views视图:一个可调用对象,一般为一个视图函数
  • 参数:可选的要传递给视图函数的默认参数(字典形式)
  • 别名:一个可选的name参数

 

补充:bash

url(r'^$', views.index), # 匹配根路径
url(r'', views.index), # 匹配根路径,这样会形成问题,这个语句放在最上面那么,访问全部网页都将走这个匹配

注意:app

  • 若要从URL 中捕获一个值,只须要在它周围放置一对圆括号。(分组匹配
  • 不须要添加一个前导的反斜杠,由于每一个URL 都有。例如,应该是^articles 而不是 ^/articles。
  • 每一个正则表达式前面的'r' 是可选的可是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不该该转义
  • urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则再也不继续。(因此注意拦截现象)

补充:ide

  

# 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项
APPEND_SLASH=True

Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其做用就是自动在网址结尾加'/'。函数

其效果就是:工具

咱们定义了urls.py:post

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

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

访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/ 。

若是在settings.py中设置了 APPEND_SLASH=False,此时咱们再请求 http://www.example.com/blog 时就会提示找不到页面。

二:路由匹配的简单使用

经过正则分组获取url中的动态参数

(正则匹配得到的参数是字符串)

1 from django.contrib import admin
 2 from django.urls import path,re_path
 3 from app01 import views
 4 
 5 
 6 urlpatterns = [
 7     path('admin/', admin.site.urls),
 8     path('timer/', views.timer),
 9     path('articles/2003/', views.special_case_2003),  #special_case_2003(request)
10     re_path(r'articles/(\d{4})/$', views.year_archive) , #year_archive(request,分组匹配的那个参数)
11     # 匹配正则使用re_path,re_path等同于url,因此默认是没有^或$
12     re_path(r'articles/(\d{4})/(\d{2})/', views.year_month)
13 ]
14 
15 '''
16 请求的url的路径部分与url方法的正则表达式进行匹配,一旦匹配成功,则执行对应的视图函数
17 http://127.0.0.1:8000/articles/2003/
18 path="/articles/2003/"
19 
20 经过下面的方法循环匹配,匹配成功则执行对应函数:
21 for item in urlpatterns:
22    ret=re.search(item.regex,path)  #  re.search("^articles/\d{4}/$","articles/2008/") 
23    if ret:
24        item.function(request)
25 '''
urls.py

 

三:路由的分组命名匹配

给分组起一个名字,实现关键字传参

上面的示例使用简单的、没有命名的正则表达式组(经过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。

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

重写urls.py

 1 from django.contrib import admin
 2 from django.urls import path,re_path
 3 from app01 import views
 4 
 5 
 6 urlpatterns = [
 7     path('admin/', admin.site.urls),
 8     path('timer/', views.timer),
 9     path('articles/2003/', views.special_case_2003),  #special_case_2003(request)
10     re_path(r'articles/(\d{4})/$', views.year_archive) , #year_archive(request,分组匹配的那个参数)
11     # 匹配正则使用re_path,re_path第一个参数默认有^尖角号
12     # re_path(r'articles/(\d{4})/(\d{2})/', views.year_month),
13     re_path(r'articles/(?P<year>\d{4})/(?P<month>\d{2})/', views.year_month)   #year_month(request,year=,month=)关键字参数。在views视图函数中,对应的函数的参数的形参要和分组名保持一致
14 ]

 

这个实现与前面的示例彻底相同,只有一个细微的差异:捕获的值做为关键字参数而不是位置参数传递给视图函数

在实际应用中,这意味你的URLconf 会更加明晰且不容易产生参数顺序问题的错误 —— 你能够在你的视图函数定义中从新安排参数的顺序。固然,这些好处是以简洁为代价;

 

补充:视图函数中指定默认值

 1 # urls.py中
 2 from django.conf.urls import url
 3 
 4 from . import views
 5 
 6 urlpatterns = [
 7     url(r'^blog/$', views.page),
 8     url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
 9 ]
10 
11 # views.py中,能够为num指定默认值
12 def page(request, num="1"):
13     pass
View Code

 

四:路由的分发(include)

给每个app本身的url分发各自的路由文件中

项目中咱们把每一个应用中的urls.py文件都单独放在各自的应用文件中,这样就须要总urls.py文件和各个应用中的urls.py文件联系起来,这就是从总文件中分发给各个分文件。在各个应用中须要本身建立urls.py文件

项目的urls.py

 1 from django.contrib import admin
 2 from django.urls import path,re_path,include
 3 from app01 import views
 4 
 5 
 6 urlpatterns = [
 7     # 先匹配app01/而后去app01.urls文件中匹配其余的
 8     path(r'app01/',include('app01.urls'))
 9 ]
10 
11 #如访问http://127.0.0.1:8001/app01/articles/2009/
项目的urls.py

 

五:路由的反向解析

不要硬编码url,经过别名解析url

当咱们的根据须要访问的路径须要更更名字时,那么,原来的路径就不能访问了。因此就须要更改项目中的相应有关系的这个名。但这样太过于麻烦,一个项目中,对于这个路径,可能有不少使用这个名字。这样维护成本过高,那么该怎么办呢?咱们的想法是用变量之类的方式,总之写路径时不要写死。下面就用别名的方法,只要写别名就行,那么一个地方更名就好了。


 

案例1

如urls.py文件中,起别名

url(r'^login.html/', views.login,name="XXX")

其余相关的别的文件中填写这个路径的只须要写别名



(1)模板文件中(html文件):
<form action="{% url 'XXX' %}" method="post">
       用户名 <input type="text" name="user">
       密码 <input type="password" name="pwd">
       <input type="submit">

</form>
当查询到有到
{% url 'XXX' %}就会去url里面寻找对应别名的真实名字把{% url 'XXX' %}替换成真名

(2)视图函数(py文件) 

 

1 urlpatterns = [
2     path('index/', views.index,name='in_dex'),
3 ]
urls.py
1 from django.urls import reverse
2 
3 def index(request):
4     # 找别名,获得最新的路径放在别名的位置
5     url=reverse("in_dex")
6     print(url)
views.py

 

 

案例2:

如urls.py文件中,起别名,有动态的正则,那么该怎么办呢?

re_path('books/delete/(\d+)', views.delete,name='delete')

 

在html模板文件中这样引用:

{% url 'delete' book.nid %}

把对应的动态的参数放在别名后面

 

在py文件中

from django.urls import reverse


return redirect(reverse("delete",args=(book.nid))) # redirec重定向一个页面,reverse()是用路由解析时须要加上

 

 

  

 

 


 

在须要URL 的地方,对于不一样层级,Django 提供不一样的工具用于URL 反查:

  • 在模板中:使用url 模板标签。
  • 在Python 代码中:使用django.core.urlresolvers.reverse() 函数。

urls.py:

复制代码
from django.conf.urls import url

from . import views

urlpatterns = [
    #...
    url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
    #...
]
复制代码

在模板中:

复制代码
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>

<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>
复制代码

在python中:

复制代码
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect

def redirect_to_year(request):
    # ...
    year = 2006
    # ...
    return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))   # 同redirect("/path/")
复制代码

当命名你的URL 模式时,请确保使用的名称不会与其它应用中名称冲突。若是你的URL 模式叫作comment,而另一个应用中也有一个一样的名称,当你在模板中使用这个名称的时候不能保证将插入哪一个URL。在URL 名称中加上一个前缀,好比应用的名称,将减小冲突的可能。咱们建议使用myapp-comment 而不是comment

六:命名空间

 

 命名空间(英语:Namespace)是表示标识符的可见范围。一个标识符可在多个命名空间中定义,它在不一样命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,由于已有的定义都处于其它命名空间中。

       上面反向解析中,因为name没有做用域,Django在反解URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,当即返回。咱们在开发项目时,会常用name属性反解出URL,当不当心在不一样的app的urls中定义相同的name时,可能会致使URL反解错误,为了不这种事情发生,引入了命名空间。以下示例:

       项目下urls.py文件:

urlpatterns = [
url(r'^admin/', admin.site.urls),
re_path(r'^app01/', include(('app01.urls',"app01"),namespace='app01')),
re_path(r'^app02/', include(('app02.urls',"app02"),namespace='app02')),
]

       app01下的urls.py: 

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

       app02下的urls.py:

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

       app01下的views.py:

    from django.core.urlresolvers import reverse
    def index(request):
        return  HttpResponse(reverse("app01:index"))

       app02下的views.py: 

    from django.core.urlresolvers import reverse
    def index(request):
        return  HttpResponse(reverse("app02:index"))

 


Django1版本 的路由层(URLconf):https://www.cnblogs.com/yuanchenqi/articles/8876685.html

Django2版本 的路由层(URLconf):https://www.cnblogs.com/yuanchenqi/articles/8931472.html

相关文章
相关标签/搜索