Django 路由

HammerZe發表於2022-02-28

Django 路由

image

每個應用(app)都可以有自己的templates來存放HTML檔案,查詢順序是通過app註冊的順序來查詢的;

路由分發

django是專注於開發應用的,當一個django專案特別龐大的時候,所有的路由與檢視函式對映關係全部寫在總的urls.py很明顯太冗餘不便於管理;

其實django中的每一個應用都可以有自己的urls.py,static資料夾,templates資料夾,基於上述特點,使用django做分組開發非常的簡便;

這裡的路由分發,類似專案下urls.py是總路由,應用下的urls.py是子路由,這樣各司其職,先通過總路由篩選要找的應用,在通過應用的子路由查詢對應關係及其對應的檢視函式,渲染出不同的頁面···

'''總路由分發'''
# 方式一
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import urls as app01_urls
from app02 import urls as app02_urls

urlpatterns = [
    path('admin/', admin.site.urls),
    # 路由分發
    re_path('^app01/',include(app01_urls)),
    re_path('^app02/',include(app02_urls))
]
'''app01 urls.py'''
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    re_path(r'^index/',views.index)
]
'''app01 views.py'''
def index(request):
    return HttpResponse('from app01 index')
'''app02和app01一樣'''

# 方式二:不需要匯入模組,直接點
re_path('^app01/',include('app01.urls')),
    re_path('^app02/',include('app02.urls'))

名稱空間

名稱空間的存在解決了,當多個應用在反向解析使用相同別名的時候,出現了無法自動識別情況

總路由

urlpatterns = [
    path('admin/', admin.site.urls),   # 路由分發  
    path('app01/',include(('app01.urls','app01'),namespace='app01')),    
    path('app02/',include(('app02.urls','app02'),namespace='app02'))
]

PS:注意,在使用名稱空間的時候,include函式需要傳遞兩個引數,arg和namespace, 當namespace不為空時,arg引數必須是一個二元組,除了urlpatterns不能為空之外,app_name也必須填寫

應用

'''app01 urls.py'''
from django.urls import path, re_path
from app01 import views
app_name = 'app01'  # 一定要宣告應用名
urlpatterns = [
    re_path(r'^index/',views.index,name='index'),
    re_path(r'^login/',views.login),
]
'''app01 views.py'''
from django.shortcuts import HttpResponse, reverse,render
def index(request):
    return HttpResponse('from app01 index')
def login(request):
    print(reverse('app01:index'))
    # return HttpResponse('from app01 login')
    return render(request,'home.html')
<h1>HOME</h1>
<a href="{% url 'app01:index' %}">app01</a>
<a href="{% url 'app02:index' %}">app02</a>

偽靜態

動態網頁“偽裝”成靜態網頁,在url中將地址模擬成.html結尾的樣子,看上去像似一個靜態檔案,目的是為了增加搜尋引擎收藏我們網站的概率以及SEO查詢機率;

image

本地虛擬環境

在時間開發過程中,我們會給不同的專案配備不同的環境,專案用到什麼就裝什麼,用不到的一概不裝,不同的專案直譯器環境都不一樣;

一般專案都會將專案依賴寫入requirements.txt,然後使用pip install -r requirements.txt一次性安裝依賴

image

ps:建立虛擬環境類似於你重新下載了一個純淨的python直譯器,如果反覆建立類似於反覆下載,會消耗一定的硬碟空間

image

Django版本區別

1.區別
    urls.py中的路由匹配方法
        django 1.X第一個引數正規表示式
            url()
        django 2.X和3.X第一個引數不支援正規表示式,寫什麼就匹配什麼
            path()
    如果想要使用正則,那麼2.X與3.X也有響應的方法
         from django.urls import path,re_path
        re_path 等價於 1.X裡面的url方法
 
2.轉換器
	五種常用轉換器:
    str,匹配除了路徑分隔符(/)之外的非空字串,這是預設的形式
    int,匹配正整數,包含0。
    slug,匹配字母、數字以及橫槓、下劃線組成的字串。
    uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
    path,匹配任何非空字串,包含了路徑分隔符(/)(不能用?)
 

'''總路由'''
path('app01/',include(('app01.urls','app01'),namespace='app01'))
'''子路由'''
path('home/<int:id>',views.home)
'''檢視函式'''
def home(request,id):
    return HttpResponse('from app01 home')

ps:django1.x拿到的資料都是str,這裡的轉換器可以將資料型別自動轉換;

自定義轉換器

class MonthConverter:
        regex='\d{2}' # 屬性名必須為regex

        def to_python(self, value):
            return int(value)

        def to_url(self, value):
            return value # 匹配的regex是兩個數字,返回的結果也必須是兩個數字
'''使用自定義轉換器'''        
    from django.urls import path,register_converter
    from app01.path_converts import MonthConverter

    register_converter(MonthConverter,'mon')

    from app01 import views


    urlpatterns = [
        path('articles/<int:year>/<mon:month>/<slug:other>/', views.article_detail, name='aaa'),

  ]

JsonResponse

前後端資料互動,資料格式要求為json格式資料,這裡提供了JsonResponse來轉換

json模組序列化

def func(request):
    dic_json = {'name':'Hammer澤','age':18}
    import json
    res = json.dumps(dic_json,ensure_ascii=False)
    return HttpResponse(res)

image

psensure_ascii=False取消中文自動轉碼(Unicode),使中文正常顯示

JsonResponse模組

JsonResponse底層還是json

def func(request):
    dic_json = {'name':'Hammer澤','age':18}
	from django.http import JsonResponse
    return JsonResponse(dic_json,json_dumps_params={'ensure_ascii':False})

psensure_ascii=False取消中文自動轉碼(Unicode),使中文正常顯示,JsonResponse模組取消轉碼,需要新增引數json_dumps_params={'ensure_ascii':False}

非字典型別序列化需要新增引數

def func(request):
    lit_json = [1,2,3,4]
    from django.http import JsonResponse
    return JsonResponse(lit_json,json_dumps_params={'ensure_ascii':False},safe=False)
    

注意:多看原始碼

上傳檔案

上傳檔案注意html頁面,form元素的屬性需要設定method="post"enctype="multipart/form-data"

# 模擬上傳檔案
<form action="" enctype="multipart/form-data"  method="post">
    上傳檔案:<input type="file" name="myfile">
    <input type="submit" class="btn  btn-info">
</form>

'''路由'''
path('func1/',views.func1)
'''檢視函式'''
def func1(request):
    if  request.method=='POST':
        file_obj = request.FILES.get('myfile')   # 獲取到檔案物件
        print(file_obj.name)   # 獲取檔案的名字
        with open(file_obj.name,'wb') as f:
            for line in file_obj:
                f.write(line)

    return render(request,'home.html')

'''檢視函式使用chunks,相當於迭代器提升效率'''
def func1(request):
    if  request.method=='POST':
        file_obj = request.FILES.get('myfile')   # 獲取到檔案物件
        print(file_obj.name)   # 獲取檔案的名字
        with open(file_obj.name,'wb') as f:
            for chunks in file_obj.chunks():
                f.write(chunks)

    return render(request,'home.html')

相關文章