天天看點

Django架構學習——2—(視圖、URL映射、URL中添加參數、URL子產品化、Django内置轉換器、url命名與反轉、應用命名空間和執行個體命名空間、URL反轉傳遞參數)1、視圖2、URL映射3、URL中添加參數4、URL子產品化5、Django内置轉換器6、url命名與反轉7、應用命名空間和執行個體命名空間8、URL反轉傳遞參數

1、視圖

視圖一般都寫在app的views.py中。并且視圖的第一個參數永遠都是request(一個HttpRequest)對象。這個對象存儲了請求過來的所有資訊,包括攜帶的參數以及一些頭部資訊等。在視圖中,一般是完成邏輯相關的操作。比如這個請求是添加一篇部落格,那麼可以通過request來接收到這些資料,然後存儲到資料庫中,最後再把執行的結果傳回給浏覽器。視圖函數的傳回結果必須是HttpResponseBase對象或者子類的對象。

視圖檔案:book/views.py

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse


# django架構中寫視圖函數,必須要傳參request
def book(request):
    return HttpResponse("圖書首頁")           # 傳回值必須是 HttpResponse包裹住的類型


# django架構中寫視圖函數,必須要傳參request
def index(request):
    return HttpResponse("hello world")       # 傳回值必須是 HttpResponse包裹住的類型
           

定義路由檔案:項目名稱 /urls.py, 該路由檔案與其他檔案互相關聯的原因在

frist_django/settings.py

檔案中的

ROOT_URLCONF = 'frist_django.urls'

設定,frist_django是項目app名稱。

"""frist_django URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.http import HttpResponse
from book.views import book             # 從其他app子產品中導入定義的路由方法
from book.views import index


urlpatterns = [
    path('admin/', admin.site.urls),         # django預設路由前面有/,不需要添加
    path('', index),                         # 路由為/,綁定的方法是book子產品中views.py的index方法
    path('book/', book),                     # 路由為book/,綁定的方法是book子產品中views.py的index方法
]
           

2、URL映射

視圖寫完後,要與URL進行映射,也即使用者在浏覽器中輸入什麼url的時候可以請求到這個視圖函數。在使用者輸入了某個url,請求到我們的網站的時候,django會從項目的urls.py檔案中尋找對應的視圖。在urls.py檔案中有一個urlpatterns變量,以後django就會從這個變量中讀取所有的比對規則。比對規則需要使用django.urls.path函數進行包裹,這個函數會根據傳入的參數傳回URLPattern或者是URLResolver的對象。

from django.contrib import admin
from django.urls import path
from book import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/',views.book_list)
]
           

3、URL中添加參數

建立新的Django項目

# 首先先進入虛拟環境下
cd /d E:\ENV\Django項目\2-課

# 建立django項目,名稱為django_url
django-admin startproject django_url

# 進入
cd django_url\


# 建立新的app子產品,名稱為book
python manage.py startapp book
           

有時候,url中包含了一些參數需要動态調整。比如簡書某篇文章的詳情頁的url,是https://www.jianshu.com/p/a5aab9c4978e後面的a5aab9c4978e就是這篇文章的id,那麼簡書的文章詳情頁面的url就可以寫成https://www.jianshu.com/p/,其中id就是文章的id。那麼如何在django中實作這種需求呢。這時候我們可以在path函數中,使用尖括号的形式來定義一個參數。比如我現在想要擷取一本書籍的詳細資訊,那麼應該在url中指定這個參數。(後面的a5aab9c4978e就是這篇文章的id,是為了安全考慮,防止SQL注入等手段;還有就是隐藏網站中的真實文章數量等功能)

1. 第一種url傳參方式

視圖檔案:book/views.py

from django.shortcuts import render
from django.http import HttpResponse


def book(request):
    return HttpResponse("圖書首頁")


def book_detail(request, book_id, cate_id):
    return HttpResponse("圖書詳情,id為%s,分類id%s" % (book_id, cate_id))
           

定義路由檔案:項目名稱 /urls.py

from django.contrib import admin
from django.urls import path
from book import views


urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/', views.book),
    path('book/<book_id>/<cate_id>', views.book_detail), # <book_id>必須與views.book_detail方法中的參數名稱相同
]
           

使用反斜線 / 隔開傳參參數方式,實作的路由效果:

Django架構學習——2—(視圖、URL映射、URL中添加參數、URL子產品化、Django内置轉換器、url命名與反轉、應用命名空間和執行個體命名空間、URL反轉傳遞參數)1、視圖2、URL映射3、URL中添加參數4、URL子產品化5、Django内置轉換器6、url命名與反轉7、應用命名空間和執行個體命名空間8、URL反轉傳遞參數

2. 第二種url傳參方式

視圖檔案:book/views.py

from django.shortcuts import render
from django.http import HttpResponse


def book_list(request):
    print(type(request))               # 類<class 'django.core.handlers.wsgi.WSGIRequest'>
    book_id = request.GET.get('id')    # 從urls.py傳輸過來的參數id,GET是request類中的方法,request.GET傳回的是字典,get擷取字典中的參數
    return HttpResponse("圖書清單%s" % book_id)
           

定義路由檔案:項目名稱 /urls.py

from django.contrib import admin
from django.urls import path
from book import views


urlpatterns = [
    path('admin/', admin.site.urls),
   
    path('book_list/', views.book_list),   # 關鍵字傳參,不需要在路由中寫參數
]
           

關鍵字傳參,以? 号隔開傳參參數,不需要在路由中寫參數,實作的路由效果:

Django架構學習——2—(視圖、URL映射、URL中添加參數、URL子產品化、Django内置轉換器、url命名與反轉、應用命名空間和執行個體命名空間、URL反轉傳遞參數)1、視圖2、URL映射3、URL中添加參數4、URL子產品化5、Django内置轉換器6、url命名與反轉7、應用命名空間和執行個體命名空間8、URL反轉傳遞參數
def book_list(request):
    print(type(request))               # 類<class 'django.core.handlers.wsgi.WSGIRequest'>
    book_id = request.GET.get('id')    # 從urls.py傳輸過來的參數id,GET是request類中的方法,request.GET傳回的是字典,get擷取字典中的參數
    c_id = request.GET.get('cid')

    return HttpResponse("圖書清單%s, 圖書類别是%s" % (book_id, c_id))
           

多個傳參以&号隔開,根據鍵值對的參數來顯示

Django架構學習——2—(視圖、URL映射、URL中添加參數、URL子產品化、Django内置轉換器、url命名與反轉、應用命名空間和執行個體命名空間、URL反轉傳遞參數)1、視圖2、URL映射3、URL中添加參數4、URL子產品化5、Django内置轉換器6、url命名與反轉7、應用命名空間和執行個體命名空間8、URL反轉傳遞參數

4、URL子產品化

URL中包含另外一個urls子產品:

在我們的項目中,不可能隻有一個app,如果把所有的app的views中的視圖都放在urls.py中進行映射,肯定會讓代碼顯得非常亂。是以django給我們提供了一個方法,可以在app内部包含自己的url比對規則,而在項目的urls.py中再統一包含這個app的urls。使用這個技術需要借助include函數。

定義路由檔案:項目名稱 /urls.py

from django.contrib import admin
from django.urls import path, include   # include是url子產品化


urlpatterns = [
    path('admin/', admin.site.urls),
    # path('book/', views.book),
    # path('book/<book_id>/<cate_id>', views.book_detail),     # <book_id>必須與views.book_detail方法中的參數名稱相同
    # path('book_list/', views.book_list),          # 關鍵字傳參,不需要在路由中寫參數
    
    
    # url子產品化,定義book子產品的字首路由,關聯book子產品下的urls.py檔案
    path("book/", include("book.urls"))
]

           

book子產品app檔案下的路由檔案:book/urls.py

# -*- encoding: utf-8 -*-
"""
@File    : urls.py
@Time    : 2020/6/17 15:54
@Author  : chen
book子產品app檔案下的路由檔案:book/urls.py
"""
from django.urls import path
from . import views          # 引用目前檔案夾下的views.py檔案

# 此時的路由是book子產品下定義的,需要被整體項目下的urls.py檔案包含,而且路由字首是需要在django_url/urls.py檔案中定義
urlpatterns = [
    path('', views.book),
    path('book/<book_id>/<cate_id>', views.book_detail),     # <book_id>必須與views.book_detail方法中的參數名稱相同
    path('book_list/', views.book_list),                     # 關鍵字傳參,不需要在路由中寫參數
]

           

在urls.py檔案中把所有的和book這個app相關的url都移動到app/urls.py中了,django_first/urls.py中,通過include函數包含book.urls,以後在請求book相關的url的時候都需要加一個book的字首。

實作效果如下:

Django架構學習——2—(視圖、URL映射、URL中添加參數、URL子產品化、Django内置轉換器、url命名與反轉、應用命名空間和執行個體命名空間、URL反轉傳遞參數)1、視圖2、URL映射3、URL中添加參數4、URL子產品化5、Django内置轉換器6、url命名與反轉7、應用命名空間和執行個體命名空間8、URL反轉傳遞參數

5、Django内置轉換器

from django.urls import converters
           

UUID:https://www.cnblogs.com/franknihao/p/7307224.html

from django.urls import path
from . import views          # 引用目前檔案夾下的views.py檔案
from django.urls import converters

# 此時的路由是book子產品下定義的,需要被整體項目下的urls.py檔案包含,而且路由字首是需要在django_url/urls.py檔案中定義
urlpatterns = [
    path('', views.book),
    # 需要限制book_id和cate_id的資料類型,采用int類型資料
    path('book/<int:book_id>/<int:cate_id>', views.book_detail),     # <book_id>必須與views.book_detail方法中的參數名稱相同
    path('book_list/', views.book_list),                     # 關鍵字傳參,不需要在路由中寫參數
]

           

6、url命名與反轉

  • 1.為什麼需要URL命名

    因為在項目開發的過程中URL位址可能經常變動,如果寫死會經常去修改

  • 2.如何給一個URL指定名稱
  • 3.應用命名空間

    在多個app之間可能産生同名的URL,這時候為了避免這種情況,可以使用命名空間來加以區分。在urls.py中添加app_name即可。

執行個體如下:

視圖檔案:front/views.py

from django.shortcuts import render, redirect,reverse      # 重定向
from django.http import HttpResponse


def front_index(request):
    # 傳參
    username = request.GET.get('username')         # 傳參username,模拟傳遞使用者名
    if username:
        return HttpResponse("前台首頁")             # 模拟使用者登入後,轉到首頁界面
    else:                                          # 使用者未登陸的時候,需要重定向到登入界面
        # 重定向
        # return redirect('login/')                  # 位址與front/urls.py檔案中的路由位址要綁定
        return redirect(reverse('front:login'))      # 通過路由的name來進行反轉,查找到定義的路由"signin/",front:是限制該路由的應用命名空間名稱


def front_login(request):
    return HttpResponse("前台登入界面")
           

注意:代碼中的front:是限制該路由的應用命名空間名稱,防止不同app子產品命名路由相同,通路出現重定義,限制路由通路,該命名從urls.py檔案中傳入。

定義前台路由檔案:front/urls.py

# -*- encoding: utf-8 -*-
"""
@File    : urls.py
@Time    : 2020/6/17 16:56
@Author  : chen
定義前台路由檔案:front/urls.py
"""
from django.urls import path
from . import views

# 應用命名空間
app_name = "front"

urlpatterns = [
    path("", views.front_index, name="index"),
    path("signin/", views.front_login, name="login"),           # 路由名稱signin/,如果後期項目需要修改路由,隻需修改這裡的路由位址,其他的都可以不用修改了
]
           
Django架構學習——2—(視圖、URL映射、URL中添加參數、URL子產品化、Django内置轉換器、url命名與反轉、應用命名空間和執行個體命名空間、URL反轉傳遞參數)1、視圖2、URL映射3、URL中添加參數4、URL子產品化5、Django内置轉換器6、url命名與反轉7、應用命名空間和執行個體命名空間8、URL反轉傳遞參數

7、應用命名空間和執行個體命名空間

一個app,可以建立多個執行個體。可以使用多個URL映射同一個App。在做反轉的時候,如果使用應用命名空間,就會發生混淆,為了避免這個問題,可以使用執行個體命名空間,執行個體命名空間使用,namespace=‘執行個體命名空間’。

django_url/urls.py ,定義執行個體命名空間

from django.contrib import admin
from django.urls import path, include   # include是url子產品化
# from book import views


urlpatterns = [
    path('admin/', admin.site.urls),
    # path('book/', views.book),
    # path('book/<book_id>/<cate_id>', views.book_detail),     # <book_id>必須與views.book_detail方法中的參數名稱相同
    # path('book_list/', views.book_list),          # 關鍵字傳參,不需要在路由中寫參數
    
    
    # url子產品化,定義book子產品的字首路由,關聯book子產品下的urls.py檔案
    path("book/", include("book.urls")),
    path("cms/", include("cms.urls")),
    path("", include("front.urls")),       # 前台界面直接通路
    path("cms1/", include("cms.urls", namespace='cms1')),        # 執行個體命名空間
    path("cms2/", include("cms.urls", namespace='cms2')),        # 執行個體命名空間
]
           

cms/views.py, 顯示目前通路的執行個體命名空間名稱

from django.shortcuts import render
from django.http import HttpResponse


def cms_index(request):
    current_namespace = request.resolver_match.namespace             # 擷取目前通路的執行個體命名空間名稱
    print(current_namespace)
    
    return HttpResponse("背景首頁")


def cms_login(request):
    return HttpResponse("背景登入界面")
           

8、URL反轉傳遞參數

如果這個url中需要傳遞參數,那麼可以通過kwargs來傳遞參數。

因為django中的reverse反轉url的時候不區分GET請求和POST請求,是以不能在反轉的時候添加查詢字元串的參數。如果想要添加查詢字元串的參數,隻能手動的添加。

login_url = reverse("front:singin") + "?name=xxx"
return redirect(login_url)
           

兩種反轉傳遞參數方式:

front/views.py

from django.shortcuts import render, redirect,reverse      # 重定向
from django.http import HttpResponse


def front_index(request):
    # 傳參
    username = request.GET.get('username')         # 傳參username,模拟傳遞使用者名
    if username:
        return HttpResponse("前台首頁")             # 模拟使用者登入後,轉到首頁界面
    else:                                          # 使用者未登陸的時候,需要重定向到登入界面
        # 重定向
        # return redirect('login/')                  # 位址與front/urls.py檔案中的路由位址要綁定
        # return redirect(reverse('front:login'))      # 通過路由的name來進行反轉,查找到定義的路由"signin/",front:是限制該路由的應用命名空間名稱
        
        # 第一種傳參:url反轉重定向傳參,關鍵字傳參
        # return redirect(reverse('front:article', kwargs={"article_id": 3}))

        # 第二種傳參:url反轉重定向傳參,字元串拼接傳參
        return redirect(reverse('front:login') + "?name = 詳情資訊")


def front_login(request):
    name = request.GET.get('name')
    return HttpResponse("前台登入界面% s" % name)        # 這種選擇字元拼接傳參


def front_article(request, article_id):
    return HttpResponse("前台登入界面 %s" % article_id)          # 這種選擇關鍵字傳參

           

定義前台路由檔案:front/urls.py

# -*- encoding: utf-8 -*-
"""
@File    : urls.py
@Time    : 2020/6/17 16:56
@Author  : chen
定義前台路由檔案:front/urls.py
"""
from django.urls import path
from . import views

# 應用命名空間
app_name = "front"

urlpatterns = [
    path("", views.front_index, name="index"),
    path("signin/", views.front_login, name="login"),           # 路由名稱signin/,如果後期項目需要修改路由,隻需修改這裡的路由位址,其他的都可以不用修改了
    path("article/<article_id>", views.front_article, name="article"),      # 定義路由
]
           

兩種傳參方式的選擇不同,效果如下:

Django架構學習——2—(視圖、URL映射、URL中添加參數、URL子產品化、Django内置轉換器、url命名與反轉、應用命名空間和執行個體命名空間、URL反轉傳遞參數)1、視圖2、URL映射3、URL中添加參數4、URL子產品化5、Django内置轉換器6、url命名與反轉7、應用命名空間和執行個體命名空間8、URL反轉傳遞參數
Django架構學習——2—(視圖、URL映射、URL中添加參數、URL子產品化、Django内置轉換器、url命名與反轉、應用命名空間和執行個體命名空間、URL反轉傳遞參數)1、視圖2、URL映射3、URL中添加參數4、URL子產品化5、Django内置轉換器6、url命名與反轉7、應用命名空間和執行個體命名空間8、URL反轉傳遞參數