Django 的路由系統
Django 的路由系統
路由層
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^$',views.home), url(r'^test/$',views.test), url(r'^testadd/$',views.testadd), url(r'',views.error) ]
注意:第一個參數是正則表達式,匹配規則按照從上往下一次匹配,匹配到一個以後當即匹配,直接執行對應的視圖函數html
網站首頁路由
url(r'^$',views.home)
網站不存在頁面
url(r'',views.error)
無名分組
(將加括號的正則表達式匹配到的內容當作位置參數自動傳遞給對應的視圖函數,視圖函數加一個形參接收,再經過reverse進行反向解析得完整的請求地址,這樣就能夠知道用戶訪問的是什麼資源,進行鍼對性返回)前端
# 路由 url(r'^test/(\d+)/',views.test), # 匹配一個或多個數字 # 視圖 def test(request,xxx): print(xxx) return HttpResponse('xxx')
有名分組
(將加括號的正則表達式匹配到的內容當作關鍵字參數自動傳遞給對應的視圖函數)python
# 路由 url(r'^test/(?P<year>\d+)/',views.test), # 匹配一個或多個數字 # 視圖 def test(request,year): print(year) return HttpResponse('test')
注意: 無名分組和有名分組不能混着用!!!git
url(r'^test/(\d+)/(?P<year>\d+)/',views.test) # 不能混着用
可是 支持用一類型多個形式匹配。正則表達式
無名分組多個 url(r'^test/(\d+)/(\d+)/',views.test), 有名分組多個 url(r'^test/(?P<year>\d+)/(?P<xxx>\d+)/',views.test),
反向解析
(根據名字動態獲取到對應路徑)django
名字:對視圖函數和路由的映射關係取的別名: url(r"^index/",views.index,name="aaa")json
對應路徑:可變化的 r"^index/"後端
# 路由 from django.shortcuts import reverse url(r'^index6668888/$',views.index,name='index') # 能夠給每個路由與視圖函數對應關係起一個名字 # 這個名字可以惟一標識出對應的路徑 # 注意這個名字不能重複是惟一的 # 前端使用 {% url 'index' %} {% url '你給路由與視圖函數對應關係起的別名' %} # 後端視圖函數使用 reverse('index') reverse('你給路由與視圖函數對應關係起的別名')
無名分組反向解析
# 路由 url(r'^test/(\d+)/',views.test,name='list') # 後端使用 print(reverse('list',args=(xxx,))) #xxx是視圖函數接收到的形參 # 前端使用 {% url 'list' xxx %} (xxx 不是固定的,能夠是後端渲染的變量,也但是是經過JS進行動態渲染的)
示例:markdown
# 後端傳給前端 user_list = models.User.objects.all() # 前端模板語法 {%for user_obj in user_list%} <a href='edit/{{ user_obj.pk }}/'></a> {% endfor %} # —————————————————————————————————————————— # # Django路由 url(r'^edit/(\d+)/',views.edit,name='edit') # 後端視圖函數 from django.shortcuts import reverse def edit(request,edit_id): url = reverse('edit',args=(edit_id,)) # 使用模板爲 {% url 'edit' edit_id %}
有名分組反向解析
後端使用 # 後端有名分組和無名分組均可以用這種形式 print(reverse('list',args=(10,))) # 下面這個瞭解便可 print(reverse('list',kwargs={'year':10})) 前端使用 # 前端有名分組和無名分組均可以用這種形式 {% url 'list' 10 %} # 下面這個瞭解便可 {% url 'list' year=10 %}
總結:針對有名分組與無名分組的反向解析統一採用一種格式便可
後端 def viewname(request,xxx): reverse('list',args=(xxx,)) # 這裏的數字一般都是數據的主鍵值 前端 {% url 'list' xxx %}
反向解析的本質:就是獲取到一個可以訪問名字所對應的視圖函數
路由分發
django每個app下面均可以有本身的urls.py路由層,templates文件夾,static文件夾app
項目名下urls.py(總路由)再也不作路由與視圖函數的匹配關係而是作路由的分發
from django.conf.urls import include
# 路由分發 注意路由分發總路由千萬不要$結尾
url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls))
# 在應用下新建urls.py文件,在該文件內寫路由與視圖函數的對應關係便可
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^index/',views.index)
]
名稱空間(瞭解)
url(r'^app01/',include(app01_urls,namespace='app01')), url(r'^app02/',include(app02_urls,namespace='app02')) app01.urls.py from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^index/',views.index,name='index') ] app02.urls.py from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^index/',views.index,name='index') ] app01.views.py reverse('app01:index') app02.views.py reverse('app02:index')
僞靜態網頁
搜索優化seo
url(r'^index.html',views.index,name='app01_index')
虛擬環境
不一樣的項目配置不一樣的python解釋器 django1.0與django2.0之間的區別 django2.0裏面的path第一個參數不支持正則,你寫什麼就匹配,100%精準匹配 django2.0裏面的re_path對應着django1.0裏面的url 雖然django2.0裏面的path不支持正則表達式,可是它提供五個默認的轉換器 str,匹配除了路徑分隔符(/)以外的非空字符串,這是默認的形式 int,匹配正整數,包含0。 slug,匹配字母、數字以及橫槓、下劃線組成的字符串。 uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。 path,匹配任何非空字符串,包含了路徑分隔符(/)(不能用?)
django1.0與django2.0之間的路由的區別
django2.0裏面的path第一個參數不支持正則,你寫什麼就匹配,100%精準匹配
django2.0裏面的re_path對應着django1.0裏面的url
雖然django2.0裏面的path不支持正則表達式,可是它提供五個默認的轉換器
str,匹配除了路徑分隔符(/)以外的非空字符串,這是默認的形式
int,匹配正整數,包含0。
slug,匹配字母、數字以及橫槓、下劃線組成的字符串。
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path,匹配任何非空字符串,包含了路徑分隔符(/)(不能用?)
自定義轉換器
1.正則表達式 2.類 3.註冊 # 自定義轉換器 class FourDigitYearConverter: regex = '[0-9]{4}' def to_python(self, value): return int(value) def to_url(self, value): return '%04d' % value # 佔四位,不夠用0填滿,超了則就按超了的位數來! register_converter(FourDigitYearConverter, 'yyyy') PS:路由匹配到的數據默認都是字符串形式
FBV與CBV
FBV:基於函數的視圖
CBV:基於類的視圖
CBV: url(r'^mycls/',views.MyCls.as_view()) class MyCls(View): def get(self,request): return render(request,'index.html') def post(self,request): return HttpResponse('post') 不管是FBV仍是CBV路由層都是路由對應視圖函數內存地址 urlpatterns = [ # url(r'^mycls/',views.view) url(r'^mycls/',views.MyCls.as_view()) ] class MyCls(View): def get(self,request): return render(request,'index.html') def post(self,request): return HttpResponse('post')
小白必會三板斧
HttpResponse
render
redirect
JsonResponse
from django.http import JsonResponse def index(request): # res = {'name':'Jason大帥比','password':18} # return HttpResponse(json.dumps(res)) return JsonResponse({'name':'Jason大帥比','password':'1888888'},json_dumps_params={'ensure_ascii':False})
簡單的文件上傳
前端須要注意的點: 1.method須要指定成post 2.enctype須要改成formdata格式 後端暫時須要注意的是 1.配置文件中註釋掉csrfmiddleware中間件 2.經過request.FILES獲取用戶上傳的post文件數據
# 後端文件保存 file_obj = request.FILES.get('my_file') print(file_obj.name) with open(file_obj.name,'wb') as f: for line in file_obj.chunks(): f.write(line)