Django 路由層

Django的下載與基本命令

  • 下載Django:pip3 install django==2.0.1
  • 建立一個django project: django-admin startproject luffy
  • 在mysite目錄下建立應用:python manage.py startapp app01
  • 啓動django項目:python manage.py runserver 8080 咱們訪問:http://127.0.0.1:8080/時就能夠看到:
  • python manage.py makemigrations
  • python manage.py migrate
  • python manage.py createsuperuser
  • 命令行查看django版本:python -m django --version

1、文件介紹

  • manage.py ----- Django項目裏面的工具,經過它能夠調用django shell和數據庫等。
  • settings.py ---- 包含了項目的默認設置,包括數據庫信息,調試標誌以及其餘一些工做的變量。
  • urls.py ----- 負責把URL模式映射到應用程序。

靜態文件

?
1
2
3
4
5
#在settings.py中:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
     os.path.join(BASE_DIR, 'static' ),
)

路由

URL配置(URLconf)就像Django 所支撐網站的目錄。它的本質是URL與要爲該URL調用的視圖函數之間的映射表;你就是以這種方式告訴Django,對於客戶端發來的某個URL調用哪一段邏輯代碼對應執行。html

1、簡單的路由配置

  • 若要從URL 中捕獲一個值,只須要在它周圍放置一對圓括號。
  • 不須要添加一個前導的反斜槓,由於每一個URL 都有。例如,應該是^articles 而不是 ^/articles。
  • 每一個正則表達式前面的'r' 是可選的可是建議加上。它告訴Python 這個字符串是「原始的」 —— 字符串中任何字符都不該該轉義
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 在urls.py中:
from django.urls import path,re_path
from app01 import views
 
# 路由配置: 路徑--------->視圖函數
urlpatterns = [
     path( 'admin/' , admin.site.urls),
 
     #無名分組:捕獲的值做爲位置參數傳遞給視圖函數
     re_path(r '^articles/([0-9]{4})/$' , views.year_archive), #year_archive(request,'2009')
     re_path(r '^articles/([0-9]{4})/([0-9]{2})/$' , views.month_archive), # month_archive(request,'2009','12')
     re_path(r '^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$' , views.article_detail), # month_archive(request,'2009','12','1'),# month_archive(request,'2009','12','13')
 
     #有名分組:捕獲的值做爲關鍵字參數傳遞給視圖函數
     re_path(r '^articles/(?P<year>[0-9]{4})/$' , views.year_archive), # month_archive(request, year='2005')
     re_path(r '^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$' , views.month_archive), # month_archive(request, year='2005', month='03')
     re_path(r '^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$' , views.article_detail), # month_archive(request, year='2003', month='03', day='03')
 
]

2、分發

?
1
2
3
4
5
6
7
8
9
10
11
# 在urls.py中:
from django.urls import path, re_path, include
 
urlpatterns = [
     path( 'admin/' , admin.site.urls),
 
     # 分發
     re_path(r "^app01/" , include( "app01.urls" )),
     re_path(r "^app02/" , include( "app02.urls" )),
     re_path(r "^" , include( "app01.urls" )),
]

3、反向解析

得到URL 的最終形式,,對於不一樣層級,Django 提供不一樣的工具用於URL 反查:python

  • 在模板中:使用url 模板標籤。
  • 在Python 代碼中:使用from django.urls import reverse
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 在urls.py中:
from django.urls import path, re_path, include
from app01 import views
 
urlpatterns = [
     path( 'admin/' , admin.site.urls),
 
     # 反向解析
     path( 'login.html/' , views.login, name = "Log" ),
     re_path(r '^articles/([0-9]{4})/$' , views.year_archive, name = 'news-year-archive' ),
     re_path(r '^articles/(?P<year>[0-9]{4})/$' , views.year_archive, name = 'news-year' ),
 
]
 
# 在模板中:注意參數
"""
<form action="{% url 'Log' %}" method="post"></form>
 
<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>
<!--多個參數-->
<a href="{% url "n4" i1 i2 %}">編輯</a>
"""
 
# 在views.py中:
from django.urls import reverse
from django.shortcuts import render, HttpResponse, redirect
 
 
def redirect_to_year(request):
     # 無參
     url = reverse( 'Log' )
     print (url)
 
     # 有參
     year = 2006
     url88 = reverse( 'news-year-archive' , args = (year,))
     url99 = reverse( 'news-year' , kwargs = { 'year' : 2008 })
 
     return HttpResponse( 'OK' )

4、名稱空間

命名空間(英語:Namespace)是表示標識符的可見範圍。一個標識符可在多個命名空間中定義,它在不一樣命名空間中的含義是互不相干的。咱們在開發項目時,會常用name屬性反解出URL,當不當心在不一樣的app的urls中定義相同的name時,可能會致使URL反解錯誤,爲了不這種事情發生,引入了命名空間。git

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 在urls.py中:
from django.urls import path, re_path, include, url
 
urlpatterns = [
     path( 'admin/' , admin.site.urls),
 
     # 分發
     re_path(r "^app01/" , include( "app01.urls" )),
     re_path(r "^" , include( "app01.urls" )),
 
     # 兩個應用中,URL 模式名字同樣時:
     re_path(r "^app01/" , include(( "app01.urls" , "app01" ))),
     re_path(r "^app02/" , include(( "app02.urls" , "app02" ))),
 
]
# 模板中
{ % url 'app01:index' % }
{ % url 'app02:index' pk = item. id % }  帶參數的
 
# app01中的urls.py
from django.urls import path, re_path
from app01 import views
 
urlpatterns = [
     re_path( "index/" , views.index, name = "index" )
]
 
# app02中的urls.py
from django.urls import path, re_path
from app02 import views
 
urlpatterns = [
     re_path( "index/" , views.index, name = "index" )
]
 
# app01中的views.py
from django.shortcuts import render, HttpResponse,redirect
from django.urls import reverse
 
 
def index(reqeust):
     return redirect(reverse( "app01:index" ))
 
 
# app02中的views.py
from django.shortcuts import render, HttpResponse
from django.urls import reverse
 
 
def index(reqeust):
     return redirect(reverse( "app02:index" ))

一、注意

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 'Specifying a namespace in include() without providing an app_name '
"""
方法1:在proj/urls.py中修改
"""
urlpatterns = [
     # url(r'^rbac/', include('rbac.urls', namespace='rbac')),
     url(r '^rbac/' , include(( 'rbac.urls' , 'rbac' ), namespace = 'rbac' )),
]
 
"""
方法2:在rbac/urls.py中 添加 app_name='rbac'
"""
app_name = 'rbac'
urlpatterns = [
     url(r '^role/list/$' , role.role_list, name = 'role_list' ),  # rbac:role_list
     ...
]
 
"""
'ForeignKey' object has no attribute 'rel'
"""
self .remote_field = rel
 
# return SearchGroupRow(title, field_object.rel.model.objects.filter(**db_condition), self, request.GET)
return SearchGroupRow(title, field_object.remote_field.model.objects. filter ( * * db_condition), self , request.GET)

5、django2.0版的path

一、基本實例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 在urls.py中:
from django.urls import path, re_path
from app01 import views
urlpatterns = [
     re_path( 'articles/(?P<year>[0-9]{4})/' , views.year_archive),
     re_path( 'article/(?P<article_id>[a-zA-Z0-9]+)/detail/' , views.detail_view),
     re_path( 'articles/(?P<article_id>[a-zA-Z0-9]+)/edit/' , views.edit_view),
     re_path( 'articles/(?P<article_id>[a-zA-Z0-9]+)/delete/' , views.delete_view),
]
"""
1.函數 year_archive 中year參數是字符串類型的
2.三個路由中article_id都是一樣的正則表達式,可是你須要寫三遍,當以後article_id規則改變後,須要同時修改三處代碼,
在Django2.0中,可使用 path 解決以上的兩個問題。
"""
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( 'articles/<int:year>/<int:month>/<slug>/' , views.article_detail),
]

二、基本規則

  • 使用尖括號(<>)從url中捕獲值。
  • 捕獲值中能夠包含一個轉化器類型(converter type),好比使用 捕獲一個整數變量。若果沒有轉化器,將匹配任何字符串,固然也包括了 / 字符。
  • 無需添加前導斜槓。

三、path轉化器

Django默認支持如下5個轉化器:正則表達式

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

四、註冊自定義轉化器

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

  • regex 類屬性,字符串類型
  • to_python(self, value) 方法,value是由類屬性 regex 所匹配到的字符串,返回具體的Python變量值,以供Django傳遞到對應的視圖函數中。
  • to_url(self, value) 方法,和 to_python 相反,value是一個具體的Python變量值,返回其字符串,一般用於url反向引用。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# urls.py:
from django.urls import register_converter, path
from app01 import yearconvert,views
 
#使用register_converter 將其註冊到URL配置中:
register_converter(yearconvert.FourDigitYearConverter, 'yyyy' )
 
urlpatterns = [
     path( 'articles/<yyyy:year>/' , views.year_archive),
]
 
#app01.yearconvert.py:
class FourDigitYearConverter:
     regex = '[0-9]{4}'  #規則
     def to_python( self , value):
         return int (value) # 在這轉換了類型
     def to_url( self , value):
         return '%04d' % value
 
#app01.views.py:
from django.shortcuts import render,HttpResponse,redirect
def year_archive(request,year):
     print (year, type (year))
     return HttpResponse( 'ok' )

MVC與MTV模型

1、MVC

Web服務器開發領域裏著名的MVC模式,所謂MVC就是把Web應用分爲模型(M),控制器(C)和視圖(V)三層,他們之間以一種插件式的、鬆耦合的方式鏈接在一塊兒,模型負責業務對象與數據庫的映射(ORM),視圖負責與用戶的交互(頁面),控制器接受用戶的輸入調用模型和視圖完成用戶的請求,其示意圖以下所示:數據庫

2、MTV

Django的MTV模式本質上和MVC是同樣的,也是爲了各組件間保持鬆耦合關係,只是定義上有些許不一樣,Django的MTV分別是:django

  • M 表明模型(Model): 負責業務對象和數據庫的關係映射(ORM)。
  • T 表明模板 (Template):負責如何把頁面展現給用戶(html)。
  • V 表明視圖(View): 負責業務邏輯,並在適當時候調用Model和Template。
  • 除了以上三層以外,還須要一個URL分發器,它的做用是將一個個URL的頁面請求分發給不一樣的View處理,View再調用相應的Model和Template,MTV的響應模式以下所示:

相關文章
相關標籤/搜索