Django 的路由系統

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)
相關文章
相關標籤/搜索