日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Web框架之Django_03 路由层了解(路有层 无名分组、有名分组、反向解析、路由分发 视图层 JsonResponse,FBV、CBV、文件上传)

發布時間:2024/9/30 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Web框架之Django_03 路由层了解(路有层 无名分组、有名分组、反向解析、路由分发 视图层 JsonResponse,FBV、CBV、文件上传) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

閱讀目錄

  • 一、路由層:(Django的路由系統)

  • 二、偽靜態網頁和虛擬環境:

  • 三、FBV與CBV、JsonResponse、文件上傳

一、路由層:(Django的路由系統)

  • URL配置(Django項目urls.py路由文件):
    就像Django所支撐網站的目錄,它的本質是URL與要為該URL調用的視圖函數之間的映射表。
    以這種方式告訴Django,對于這個URL調用這段代碼,對于那個URL調用那段代碼。 urls.py配置基本格式:
  • -------------------------------------------------------------------- 注:如果你對python感興趣,我這有個學習Python基地,里面有很多學習資料,感興趣的+Q群:895817687 --------------------------------------------------------------------from django.conf.urls import url from django.contrib import admin from app01 import viewsurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^$', views.index),url(r'^index/', views.index, name='index'), ]url(正則表達式, views視圖函數,參數,別名)

    參數說明:

    • 正則表達式:一個正則表達式字符串
    • views視圖函數:一個可調用對象,通常為一個視圖函數或一個指定視圖函數路徑的字符串
    • 參數:可選的要傳遞給視圖函數的默認參數(字典形式)
    • 別名:一個可選的name參數

    2:正則表達式詳解:

    from django.conf.urls import url from . import views urlpatterns = [url(r'^articles/2003/$', views.special_case_2003),url(r'^articles/([0-9]{4})/$', views.year_archive),url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]

    注意事項

    • urlpatterns中的元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則不再繼續。
    • 若要從URL中捕獲一個值,只需要在它周圍放置一對圓括號(分組匹配)。
    • 不需要添加一個前導的反斜杠,因為每個URL 都有。例如,應該是^articles 而不是 ^/articles。
    • 每個正則表達式前面的’r’ 是可選的但是建議加上。

    補充說明

    # 是否開啟URL訪問地址后面不為/跳轉至帶有/的路徑的配置項 APPEND_SLASH=TrueDjango settings.py配置文件中默認沒有 APPEND_SLASH 這個參數,但 Django 默認這個參數為 APPEND_SLASH = True。 其作用就是自動在網址結尾加'/'。其效果就是:我們定義了urls.py: from django.conf.urls import url from app01 import viewsurlpatterns = [url(r'^blog/$', views.blog), ]訪問 http://www.example.com/blog 時,默認將網址自動轉換為 http://www.example.com/blog/ 。如果在settings.py中設置了 APPEND_SLASH=False,此時我們再請求 http://www.example.com/blog 時就會提示找不到頁面。

    3:無名分組

    將加括號的正則表達式匹配到的內容當做位置參數自動傳遞給對應的視圖函數

    url(r'^test/(\d+)/',views.test), # 匹配一個或多個數字 def test(request,xxx):print(xxx)return HttpResponse('test') 這里的xxx就是test/路徑后面的數字(當然正則匹配到的字符串類型的數字)

    4:有名分組
    將加括號的正則表達式匹配到的內容當做關鍵字參數自動傳遞給對應的視圖函數)

    url(r'^test/(?P<year>\d+)/',views.test), # 匹配一個或多個數字 def test(request,year):print(year)return HttpResponse('test')

    需要注意:無名分組和有名分組不能混著用

    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)

    反向解析(根據名字動態后去到相對路徑)

    from django.shortcuts import reverse # 導入一個reverse模塊用于解析名字url(r'^index6668888/$',views.index,name='index')

    #可以給每一個路由與視圖函數對應關系起一個名字
    #這個名字能夠唯一標識出對應的路徑
    #注意這個名字不能重復是唯一的

    使用情景:

    前端使用{% url 'index' %}{% url '你給路由與視圖函數對應關系起的別名' %}后端使用reverse('index')reverse('你給路由與視圖函數對應關系起的別名')

    無名分組反向解析:

    url(r'^test/(\d+)/',views.test,name='list')

    使用情景:

    后端使用url = reverse('name',args=(10,)) # 這里的url就是前端進入后端的url路由,但是這個路由有點特別,因為他加入了無名分組參數,name就是對應路由設置的name=‘’,二后面的args=(10,)是路由正則里面匹配到的分組數字(該數字是前端傳過來的),這里寫10還是其它數字都可以,只要能讓正則匹配到。前端使用{% url 'name' 10 %} # 固定格式,路由名字,分組參數user_list = models.User.objects.all()url(r'^edit/(\d+)/',views.edit,name='edit') 前端模板語法 {%for user_obj in user_list%}<a href='edit/{{ user_obj.pk }}/'></a> {% endfor %} 可以替換為: {%for user_obj in user_list%}<a href='{% url 'edit' {{ user_obj.pk }} %}'></a> {% endfor %}

    有名分組反向解析:

    后端使用# 后端有名分組和無名分組都可以用這種形式print(reverse('list',args=(10,)))# 下面這個了解即可print(reverse('list',kwargs={'year':10}))前端使用# 前端有名分組和無名分組都可以用這種形式{% url 'list' 10 %}# 下面這個了解即可{% url 'list' year=10 %}

    總結:
    針對有名分組與無名分組的反向解析統一采用一種格式即可

    后端reverse('list',args=(10,)) # 這里的數字通常都是數據的主鍵值前端{% url 'list' 10 %}

    反向解析的實質:就是獲取到一個能夠訪問名字所對應的視圖函數(用這個名字在映射路由字符串與視圖函數的關系,同時不管路由內容怎么變,都不會改變對應的視圖函數。相當于將url配置中的一條url映射關系打上標簽,不管里面的內容怎么變,我值會找到路由與視圖函數之間的指向關系。

    6:路由分發
    需要知道:
    Django項目每一個app下面都可以有自己的urls.py路由層,templates文件夾,static文件夾
    當項目過多的時候,把所有的路由全部放在項目的url.py文件是不明智的,因為太多容易出現混亂情況
    所以可以將:
    項目名下urls.py我們統稱為總路由,它不再做路由與視圖函數的匹配關系而是做理由的分配工作
    然后分配到各個app中的url.py文件去做路由與視圖函數關系的工作。

    # 路由分發 注意路由分發總路由千萬不要$結尾 from django.conf.urls import url, include # 額外導入一個include模塊 from django.contrib import adminurl(r'^app01/',include('app01.urls')), # 注意是字符串格式url(r'^app02/',include('app02.urls')), # 注意是字符串格式# 在應用下新建urls.py文件,在該文件內寫路由與視圖函數的對應關系即可from django.conf.urls import urlfrom app01 import viewsurlpatterns = [url(r'^index/',views.index)]

    名稱空間:當多個app下面的urls.py中存在相同name的url的時候,如果不做任何處理,Django是不會識別到的,所以需要引用一個名稱空間的概念。
    在路由分發的時候為每一個app的路由分配一個名稱空間:

    url(r'^app01/',include(app01_urls,namespace='app01')), url(r'^app02/',include(app02_urls,namespace='app02'))

    各app中的路由照常添加:

    app01.urls.pyfrom django.conf.urls import urlfrom app01 import viewsurlpatterns = [url(r'^index/',views.index,name='index')]app02.urls.pyfrom django.conf.urls import urlfrom app02 import viewsurlpatterns = [url(r'^index/',views.index,name='index')]

    是視圖界面和前端使用的時候,就會跳出選擇項讓你選擇哪個app中的路由對應的name(同時表現形式會改變)

    app01.views.pyreverse('app01:index')app02.views.pyreverse('app02:index')

    注意:名稱空間的概念只做了解,因為真實我們在項目中,路由中的name=’'一般都會在前綴加上app01_index,app02_index來區分,所以不會出現重復混亂情況,這時候再用名稱空間的操作就非常的雞肋,所以只作了解。

    二、偽靜態網頁和虛擬環境:

    偽靜態網頁:
    顧名思義,偽裝成靜態網頁,實際上是動態頁面,只不過末尾加上了一串.html的字符串,而不是靜態頁面文件的后綴名。
    目的:搜索優化SEO(實際沒卵用,不如RMB玩家)
    實現:

    url(r’^index.html’,views.index,name=‘app01_index’)

    2:虛擬環境:
    為不同的項目配置不同的版本Python解釋器以適應不同項目的Python解釋器版本需求以及其支持的第三方模塊,提高項目的效率,去除不必要的模塊導致項目的加載的速度減慢。
    方法:
    新建項目>>Virtualenv>>選擇Python版本>>
    得到了一個不帶任何第三方包的“干凈”的Python虛擬環境,已經安裝到系統Python環境中的所有第三方包都不會復制過來。

    當需要安裝該環境所需要的包時,在設置—項目—Project Interpreter中點右上角的加號,搜索包名稱后點擊Install Package即可。

    注意:這里安裝的python包只在這個虛擬環境中生效,其他的虛擬環境,該怎么裝還怎么裝。
    補充:用虛擬環境實現不同版本的Django共存,比如1.0版和2.0版,所以提一下兩個版本的區別:
    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、JsonResponse、文件上傳

    FBV:基于函數的視圖,function base views
    基于函數的視圖我們在學習Django的時候就已經在使用了:

    from django.conf.urls import url from django.contrib import admin from app01 import viewsurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^$', views.index),url(r'^index/', views.index, name='index'),def test(request):if request.method == 'POST':print(request.POST)print(request.POST.get('name'), request.POST.get('pwd'))return HttpResponse('nice')return render(request, 'test.html')

    CBV:基于類的視圖與,class base views
    需要重點理解并掌握的是CBV的理解與使用:

    路由層urls.py url(r'^mycls/', views.MyCls.as_view())視圖層views.py class MyCls(View):def get(self, request):return render(request, 'index.html')def post(self, request):return render HttpResponse('post')

    源代碼解析:

    路由層urls.py
    url(r’^mycls/’, views.MyCls.as_view())中:

    MyCls類中定義了2個方法get和post
    進入MyCls繼承的類View源碼看看:
    首先在url路由層視圖那里:
    views.MyCls.as_view()
    我們在源碼中看到as_view()返回的是一個view的函數名,那么上面的可以寫成:
    views.view
    也就是這樣:
    url(r’^mycls/’,views.view)
    也就是說變成了一個視圖函數,所有接下來我們還得看看View類中的view方法的內容
    當瀏覽器發出路由請求,匹配到前面的mycls就會調用后面的視圖函數view(request)
    繼續查看dispatch函數代碼:
    所以最好view(request)函數的調用最后變成了這樣:MyCls類實例化對象self.post(request),我們再看看MyCls類的內容:
    這里就實現了通過類視圖,創建的相對于類來通過post和get(或者其它更多請求方式)來判斷請求方式進行不同的操作,達到和函數視圖方式一樣的結果。
    補充一個http請求方法列表:

    http_method_names = [‘get’, ‘post’, ‘put’, ‘patch’, ‘delete’, ‘head’, ‘options’, ‘trace’]
    至此基于類的視圖實現過程分析完成,整個過程走下來,發現實現的目的和函數視圖如出一轍,只不過用類來實現會多走基本路。條條道路通羅馬,只有有想法,什么方法都是方法,能達到目的就行,?乛?乛?

    JsonResponse(將相應的數據自動轉換成json格式,然后直接發送回瀏覽器)

    導入模塊 from django.http import JsonResponse import json原始方法: def index(request):res = {'name':'sgt','password':18}return HttpResponse(json.dumps(res))JsonResponse方法: def index(request): return JsonResponse({'name':'sgt','password':'1888888'},json_dumps_params={'ensure_ascii':False}) 注意:json_dumps_params={'ensure_ascii':False}這個的作用是,將Django默認轉碼功能取消,這樣就能顯示漢字了。
  • 文件上傳 實現過程: 前端:
  • <body> <h1>index</h1> <form action="" method="post" enctype="multipart/form-data"><input type="file" name="my_file"><input type="submit"> </form> </body>

    前端需要注意的點:
    1.method需要指定成post
    2.enctype需要改為multipart/form-data格式
    后端:

    def index(request):if request.method == '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)return HttpResponse('成功')return render(request, 'index.html')

    后端需要注意:
    1.配置文件中注釋掉csrfmiddleware
    2.通過request.FILES獲取用戶上傳的post文件數據

    補充:request中有很多屬性,這里說說里面的2個屬性:path和full_path的區別:

    def login(request):print('path:',request.path)print('full_path:',request.get_full_path())if request.method == 'POST':return HttpResponse('登錄成功')return render(request, 'login.html')path: /login/full_path: /login/?name=jason 如果路由后面有拼接字符串,會顯示

    總結

    以上是生活随笔為你收集整理的Web框架之Django_03 路由层了解(路有层 无名分组、有名分组、反向解析、路由分发 视图层 JsonResponse,FBV、CBV、文件上传)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。