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
一、文件介紹
- 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調用哪一段邏輯代碼對應執行。
一、簡單的路由配置
- 若要從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') ] |
二、分發
?| 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")), ] |
三、反向解析
獲得URL 的最終形式,,對于不同層級,Django 提供不同的工具用于URL 反查:
- 在模板中:使用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') |
四、名稱空間
命名空間(英語:Namespace)是表示標識符的可見范圍。一個標識符可在多個命名空間中定義,它在不同命名空間中的含義是互不相干的。我們在開發項目時,會經常使用name屬性反解出URL,當不小心在不同的app的urls中定義相同的name時,可能會導致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 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、注意
?| 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) |
五、django2.0版的path
1、基本實例
?| 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), ] |
2、基本規則
- 使用尖括號(<>)從url中捕獲值。
- 捕獲值中可以包含一個轉化器類型(converter type),比如使用 捕獲一個整數變量。若果沒有轉化器,將匹配任何字符串,當然也包括了 / 字符。
- 無需添加前導斜杠。
3、path轉化器
Django默認支持以下5個轉化器:
- str,匹配除了路徑分隔符(/)之外的非空字符串,這是默認的形式
- int,匹配正整數,包含0。
- slug,匹配字母、數字以及橫杠、下劃線組成的字符串。
- uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
- path,匹配任何非空字符串,包含了路徑分隔符
4、注冊自定義轉化器
對于一些復雜或者復用的需要,可以定義自己的轉化器。轉化器是一個類或接口,它的要求有三點:
- 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模型
一、MVC
Web服務器開發領域里著名的MVC模式,所謂MVC就是把Web應用分為模型(M),控制器(C)和視圖(V)三層,他們之間以一種插件式的、松耦合的方式連接在一起,模型負責業務對象與數據庫的映射(ORM),視圖負責與用戶的交互(頁面),控制器接受用戶的輸入調用模型和視圖完成用戶的請求,其示意圖如下所示:
二、MTV
Django的MTV模式本質上和MVC是一樣的,也是為了各組件間保持松耦合關系,只是定義上有些許不同,Django的MTV分別是:
- M 代表模型(Model): 負責業務對象和數據庫的關系映射(ORM)。
- T 代表模板 (Template):負責如何把頁面展示給用戶(html)。
- V 代表視圖(View): 負責業務邏輯,并在適當時候調用Model和Template。
- 除了以上三層之外,還需要一個URL分發器,它的作用是將一個個URL的頁面請求分發給不同的View處理,View再調用相應的Model和Template,MTV的響應模式如下所示:
轉載于:https://www.cnblogs.com/bubu99/p/10258417.html
總結
以上是生活随笔為你收集整理的Django 路由层的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BZOJ5093图的价值(斯特林数)
- 下一篇: 更多Requests的小技巧以及总结