1. 程式人生 > 程式設計 >Django 路由層URLconf的實現

Django 路由層URLconf的實現

分組

分組的目的:讓服務端獲得url中的具體資料,通過分組,把需要的資料按函式傳參的方式傳遞給伺服器後臺

1-無名分組

若要從URL 中捕獲一個值,只需要在它周圍放置一對圓括號

# app01/urls.py
from django.urls import path,re_path
from app01 import views


app_name = "app01"
urlpatterns = [

  path("login/",views.login,name="Log"),re_path(r"articles/([0-9]{4})/([0-9]){2}/",views.articles),]

# app01/views.py
def articles(request,year,month ):
  print(year,month)
  return HttpResponse(year+"-"+month)

2-有名分組

在更高階的用法中,可以使用命名的正則表示式組來捕獲URL 中的值並以關鍵字 引數傳遞給檢視。

在Python 正則表示式中,命名正則表示式組的語法是(?P<name>),其中name 是組的名稱,下面是以上URLconf 使用命名組的重寫。

# app01/urls.py
from django.urls import path,re_path
from app01 import views

app_name = "app01"
urlpatterns = [

  path("login/",re_path(r"articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2}/)",]

捕獲的值作為關鍵字引數而不是位置引數傳遞給檢視函式

# app01/views.py
def articles(request,month,year ):
  print(year,month)
  return HttpResponse(year+"-"+month)

分發

分發的目的:解決一個django專案中因為存在多個應用app導致project下面的urls臃腫和分配混亂的問題

分發的具體操作流程是:

step1:專案檔案下的urls.py,使用include()

# project/urls.py
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
  path('admin/',admin.site.urls),path(r"app01/",include("app01.urls")),]

step2:app下的具體url

# app01/urls.py
from django.urls import path
from app01 import views

urlpatterns = [
  path("login/",views.login),]

step3:檢視函式render時模板路徑字首

# app01/views.py
from django.shortcuts import render
# Create your views here.

def login(request):

  return render(request,"app01/login.html")

step4:模板

# app01/templates/app01/login.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>app01_title</title>
</head>
<body>
  <h2>app01_login</h2>
  <hr>
  <form action="" method="post">
    <p>使用者名稱 <input type="text" name="name"></p>
    <p>密碼 <input type="password" name="pwd"></p>
    <p><input type="submit" value="登入"></p>
  </form>

</body>
</html>

反向解析

反向解析的目的:解決url硬編碼的問題,即不能寫死一個url,否則日後修改url,造成的維護成本巨大

此時可以給url命名,然後可以在檢視和模板中使用url別名,反向解析出正式的url

反向解析分兩種:模板中解析、檢視中解析

模板中解析 <form action="{% url "Art" 12 %}" method="post">

# app01/urls.py
from django.urls import path
from app01 import views

urlpatterns = [

  path("login/",path("articles/<int:id>/",views.articles,name="Art"),#有參

]

# app01/templates/app01/login.html
<form action="{% url "Log" %}" method="post">
  <p>使用者名稱 <input type="text" name="name"></p>
  <p>密碼 <input type="password" name="pwd"></p>
  <p><input type="submit" value="登入"></p>
</form>

<form action="{% url "Art" 12 %}" method="post">
  <p>使用者名稱 <input type="text" name="name"></p>
  <p>密碼 <input type="password" name="pwd"></p>
  <p><input type="submit" value="登入"></p>
</form>

檢視中解析 reverse("Art",args=(id,))

# app01/views.py
from django.shortcuts import render
from django.urls import reverse

# Create your views here.

def login(request):
  
  print(reverse('log'))
  id=10
  print(reverse("Art",)))
  
  return render(request,"app01/login.html")

名稱空間

名稱空間要配合反向解析使用,當存在多個app,url的name衝突時,需要指定該name的名稱空間

# project/urls.py
from django.contrib import admin
from django.urls import path,include("app01.urls",namespace="app01")),path(r"app02/",include("app02.urls",namespace="app02")),]

在django2.x中,app01/url.py需要新增 app_name = "app01"

# app01/urls.py
from django.urls import path
from app01 import views

app_name = "app01"
urlpatterns = [
  path("login/",]

# app01/views.py(需要時設定)
from django.shortcuts import render
from django.urls import reverse
# Create your views here.

def login(request):
  a = reverse("app01:Log")
  print("app01:",a)
  return render(request,"app01/login.html")

# app01/templates/app01/login.html(需要時設定)
<form action="{% url "app01:Log" %}" method="post">
   <p>使用者名稱 <input type="text" name="name"></p>
   <p>密碼 <input type="password" name="pwd"></p>
   <p><input type="submit" value="登入"></p>
 </form>

轉換器

對於django2.0版本以後,出現新的path() urlconf,他有兩個好處:

1:url修改維護變得簡單

2:url獲得的引數的資料型別不再是單純的str,在path中可以通過轉換器實現引數資料型別的轉換

path()中存在5個內建轉化器:

=1. str,匹配除了路徑分隔符(/)之外的非空字串,這是預設的形式
2. int,匹配正整數,包含0。
3. slug,匹配字母、數字以及橫槓、下劃線組成的字串。
4. uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
5. path,匹配任何非空字串,包含了路徑分隔符

使用方法:

step1: app01/urls.py

from django.urls import path,re_path
from app01 import views

app_name = "app01"
urlpatterns = [
  path("login/",# re_path(r"articles/(?P<year>[0-9]{4})/",path("articles/<int:year>/<int:month>/",]

step2: app01/views.py

def articles(request,month):

  print(year,month)
  print(type(year))

  return HttpResponse("ok")

  • <int: year> 相當於re_path()中的 (?P[0-9]{4})
  • <> 表示有名分組,year是組名;int表示傳參的資料型別是正整數(但包括0)

自定義轉換器

step1: app01/my_converters.py

class YearConverter:  
  
  regex = '[0-9]{4}'  
  
  def to_python(self,value):    
    return int(value)  
  
  def to_url(self,value):    
    return '%04d' % value

step2: app01/urls.py

from django.urls import path,re_path,register_converter
from app01 import views,my_converters

register_converter(my_converters.YearConverter,'year')
app_name = "app01"
urlpatterns = [

  path("login/",# path("articles/<int:year>/<int:month>/",path("books/<year:y>",views.books),]

step3: app01/views.py

def books(request,y):

  print(y,type(y))
  return HttpResponse("ok,books")

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。