Django框架學習——2—(視圖、URL映射、URL中添加參數、URL模塊化、Django內置轉換器、url命名與反轉、應用命名空間和實例命名空間、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方法中的參數名稱相同
]

使用反斜線 / 隔開傳參參數方式,實現的路由效果:
在這裏插入圖片描述

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),   # 關鍵字傳參,不需要在路由中寫參數
]

關鍵字傳參,以? 號隔開傳參參數,不需要在路由中寫參數,實現的路由效果:
在這裏插入圖片描述

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))

多個傳參以&號隔開,根據鍵值對的參數來顯示
在這裏插入圖片描述

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的前綴。

實現效果如下:
在這裏插入圖片描述

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指定名稱

path("",views.index,name="index")    # 將路由地址命名爲index
  • 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/,如果後期項目需要修改路由,只需修改這裏的路由地址,其他的都可以不用修改了
]

在這裏插入圖片描述

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來傳遞參數。

reverse("book:detail",kwargs={"book_id":1})

因爲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"),      # 定義路由
]

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

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章