【Django】URL控制器

url控制器html

from django.contrib import admin
from django.urls import path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/',views.index),
]

視圖python

from django.shortcuts import render

# Create your views here.

def index(request):

    import datetime
    now=datetime.datetime.now()
    ctime=now.strftime("%Y-%m-%d %X")

    return render(request,"index.html",{"ctime":ctime})

模板git

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h4>當前時間:{{ ctime }}</h4>

</body>
</html>

URL控制器

路由配置

from django.urls import path,re_path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    # 路由配置:哪個路徑由哪個視圖函數處理
    path('timer/', views.timer),
    
    # 帶正則表達式的【路由配置】
    # special_case_2003(request)
    re_path(r'^articles/2003/$', views.special_case_2003),
    # /articles/2003/ --> views.month_archive(request)  沒有分組,不會傳參

    # 只要分組就會將分組的數據傳給year_archive:year_archive(request, 分組的數據)
    re_path(r'^articles/([0-9]{4})/$', views.year_archive),
    # /articles/2005/ --> views.year_archive(request, '2005')

    # month_archive(request, 分組的數據1, 分組的數據2)
    re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    # /articles/2005/03/ --> views.month_archive(request, '2005', '03')
]

有名分組

使用命名的正則表達式組來捕獲URL 中的值並以關鍵字 參數傳遞給視圖 r'(?P<...>)'正則表達式

from django.urls import path,re_path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    
    # /articles/2005/ --> views.year_archive(request, year='2005')
    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

    # /articles/2005/03/ --> views.month_archive(request, year='2005', month='03')
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    
]

分發

URLconf中的path能夠直接將路徑請求發送給對應的視圖函數進行處理,也能夠轉發給另外一個URLconf,使用include函數設置要轉發的URLconf,子URLconf接收到的是匹配事後的餘下字符串。下降耦合度django

project/urls.py/app

from django.urls import path,re_path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    # 將路徑請求發送給對應的視圖函數
    path('timer/', views.timer),
    
    # 轉發給另外一個URLconf,
    re_path(r'^app01/', include('app01.urls')),
    re_path(r'^app02/', include('app02.urls')),
]

app01 /urls.py/函數

from django.urls import path,re_path

from app01 import views

urlpatterns = [
    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
]

app02 /urls.py/工具

from django.urls import path,re_path

from app01 import views

urlpatterns = [
    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
]

訪問路路徑就變成了:ui

.../app01/articles/2018/.../app01/articles/2018/11url

.../app02/articles/2018/.../app02/articles/2018/11

反向解析

在須要URL 的地方,對於不一樣層級,Django 提供不一樣的工具用於URL 反查:

  1. 在模板中:使用url 模板標籤。

  2. 在Python 代碼中:使用from django.urls import reverse()函數

app01/urls.py: re_path(r'xx', views.xx, name='xxx')

from django.conf.urls import url

from . import views

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

在模板中: {% url 'xxx' xxxx %}

<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>

在views中: reverse('xxx', args=(xxxx,)

from django.urls import reverse
from django.http import HttpResponseRedirect

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

名稱空間

命名空間(英語:Namespace)是表示標識符的可見範圍。一個標識符可在多個命名空間中定義,它在不一樣命名空間中的含義是互不相干的。這樣,在一個新的命名空間中可定義任何標識符,它們不會與任何已有的標識符發生衝突,由於已有的定義都處於其它命名空間中。 因爲name沒有做用域,Django在反解URL時,會在項目全局順序搜索,當查找到第一個name指定URL時,當即返回 咱們在開發項目時,會常常使用name屬性反解出URL,當不當心在不一樣的app的urls中定義相同的name時,可能會致使URL反解錯誤,爲了不這種事情發生,引入了命名空間。

project的urls.py:

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

app01.urls:

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

app02.urls:

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

app01.views

from django.core.urlresolvers import reverse

def index(request):
    return HttpResponse(reverse("app01:index"))

app02.views

from django.core.urlresolvers import reverse

def index(request):
    return HttpResponse(reverse("app02:index"))

django2.0版的path

URLconf的示例:

from django.urls import path
from . import views

urlpatterns = [
    path('articles/2003', views.special_case_2003)
    path('articles/<int:year>/', views.year_archive),
    path('articles/<int:year>/<int:month>', views.month_archive),
]

path字符串中,可使用<>獲取符合條件的字符串,轉換成對應數據類型傳遞給views處理函數中的變量名,例如 匹配int類型的變量,傳遞給views處理函數中的year變量。若是沒有提供數據類型的話,則直接把對應字符串傳遞下去(不包括/)。

路徑匹配類型包含如下幾種:

  • str:匹配去除/後的非空字符串,這是默認的匹配方式。
  • int:匹配非零整數,返回int類型數據。
  • slug:匹配由ASCII字母或數字、以及-和_組成的字符串。
  • uuid:匹配格式化的UUID,即必須包含-,字母小寫。

  • path:匹配包含/的非空字符串。

註冊自定義轉化器:
對於一些複雜或者複用的須要,能夠定義本身的轉化器。轉化器是一個類或接口,它的要求有三點:

  1. regex 類屬性,字符串類型
  2. to_python(self, value) 方法,value是由類屬性 regex 所匹配到的字符串,返回具體的Python變量值,以供Django傳遞到對應的視圖函數中。
  3. to_url(self, value) 方法,和 to_python 相反,value是一個具體的Python變量值,返回其字符串,一般用於url反向引用。
class FourDigitYearConverter:  
    regex = '[0-9]{4}'  
    def to_python(self, value):  
        return int(value)  
    def to_url(self, value):  
        return '%04d' % value

使用register_converter 將其註冊到URL配置中:

from django.urls import register_converter, path  
from . import converters, views  

register_converter(converters.FourDigitYearConverter, 'yyyy')  

urlpatterns = [  
    path('articles/2003/', views.special_case_2003),  
    path('articles/<yyyy:year>/', views.year_archive),  
    ...  
]
相關文章
相關標籤/搜索