Django路由與視圖

路由層

一.路由匹配規則:

第一個參數是正則表達式,匹配規則按照從上往下一次匹配,匹配到一個以後當即匹配,直接執行對應的視圖函數html

url(r'login', views.login),

若是按上面的形式匹配的話就成模糊匹配了,login的前面沒有限制條件,能夠輸入任意的字符串,login的後面也沒有限制條件也是能夠輸入任意的字符串,這樣的話致使只要我路徑裏面有login這樣的關鍵字不管我輸入什麼都沒有關係,均可以訪問的到,怎麼解決方式是在前面加^h和後面加$符號,這樣的話就限制了,只要能是路徑對了才能訪問到,以下。前端

url(r'^login/$', views.login),  #而後去寫對應的視圖函數就能夠了

網站首頁路由配置:python

url(r'^$', views.login),  #而後去寫對應的視圖函數就能夠了

網頁錯誤路由設置:git

url(r'',views.error)  #而後去寫對應的視圖函數就能夠了

二.有名分組和無名分組傳參

無名分組(將加括號的正則表達式匹配到的內容當作位置參數自動傳遞給對應的視圖函數)

路由層正則表達式

url(r'^login/([0-9]{4})$', views.login),  # ([0-9]{4})匹配4個數字而後進行分組

視圖函數層django

def login(request,year): # 若是分了一個組的話必定要的對應的視圖函數加上一個函數,若是有兩個就加上兩個參數
    print(year) # http://127.0.0.1:8000/login/2019  打印結果就是2019
    return render(request,'login.html')

多個無名分組

路由層後端

url(r'^login/([0-9]{4})([0-9]{2})$', views.login), # ([0-9]{4})匹配4個數字而後進行分組  ([0-9]{2}) 匹配2個數字而後進行分組

視圖函數層:app

def login(request,*args): # 若是分了一個組的話必定要的對應的視圖函數加上一個函數,若是有兩個就加上兩個參數
    print(agrs) # http://127.0.0.1:8000/login/2019/06  打印結果就是(2019,06)
    return render(request,'login.html')

有名分組:

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

​ 注意:無名分組和有名分組不能混着用!!!post

路由層:

url(r'^index/(?P<year>\d+)/',views.index)

視圖函數層方式一:

def index(request,year):
        print(year)
        return HttpResponse('test')

視圖函數層方式二

def index(request,**kwargs):
        print(kwargs)
        return HttpResponse('test')

反向解析

根據名字動態獲取對應的路徑

前端模板方式

語法 {% url '路由的別名' %}

路由層:

url(r'^index111/', views.index,name='xxx'),
    # 能夠給每個路由與視圖函數對應關係起一個名字
    # 這個名字可以惟一標識出對應的路徑
    # 注意這個名字不能重複是惟一的

前端模

<p><a href="{% url 'xxx' %}">1111111111111</a></p>s

後端方式

語法 reverse('路由的別名')

url(r'^index111/', views.index,name='xxx'),

視圖函數層

def index(request):

    if request.method == 'POST':
        url = reverse('xxx')
        return redirect(url)
    return render(request,'index.html')

無名分組反向解析

後端

路由

url(r'^index/([0-9]{4})/', views.index,name='xxx'),

視圖函數

def index(request,*age):
   
    rl = reverse('xxx', args=(2019,))
    print(rl)
    return render(request,'index.html')
前端

路由

url(r'^index/([0-9]{4})/', views.index,name='xxx'),

前端html頁面

<p> 
    <a href='{ % url 'xxx' 2019 % }'><a>
<p>

有名分組反向解析

後端使用
        # 後端有名分組和無名分組均可以用這種形式
        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 %}
反向解析的本質:就是獲取到一個可以訪問名字所對應的視圖函數

路由分發

路由分發
    django每個app下面均可以有本身的urls.py路由層,templates文件夾,static文件夾
    項目名下urls.py(總路由)再也不作路由與視圖函數的匹配關係而是作路由的分發
路由分發的兩種方式:
    方式一:
        總路由:
            # 不須要導入任何東西
            url(r'^app01','app01.urls'),
            url(r'^app02','app02.urls')
         app01路由:
            在你建立app01的時候是app01下面是沒有urls路由的須要本身手動建立,而後
            把項目文件夾下的總路由copy到app01的路由下
            urlpatterns = [
                url(r'^index/', views.index),
                ]
    方式二:
        總路由:
            # 只須要導入include和app01與app02的urls並取別名
             而且去別名
            from django.conf.urls import url,include
           from app01 import urls as a1
           from app02 import urls as a2
            url(r'^app01',include(a1)),
            url(r'^app02',include(a2)),
             app01路由:
            在你建立app01的時候是app01下面是沒有urls路由的須要本身手動建立,而後
            把項目文件夾下的總路由copy到app01的路由下
            urlpatterns = [
                url(r'^index/', views.index),
                ]

名稱空間

名稱空間(瞭解)
# 名稱空間是避免多個app之間視圖函數名重複
    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,匹配任何非空字符串,包含了路徑分隔符(/)(不能用?)

自定義轉換器
    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
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')
簡單的文件上傳
前端須要注意的點:
    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)
相關文章
相關標籤/搜索