欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Django基礎三之視圖函數(shù)的使用方法

 更新時間:2019年07月18日 09:16:48   作者:愛文飛翔  
這篇文章主要介紹了Django基礎三之視圖函數(shù)的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一 Django的視圖函數(shù)view

一個視圖函數(shù)(類),簡稱視圖,是一個簡單的Python 函數(shù)(類),它接受Web請求并且返回Web響應。

響應可以是一張網(wǎng)頁的HTML內(nèi)容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片。

無論視圖本身包含什么邏輯,都要返回響應。代碼寫在哪里也無所謂,只要它在你當前項目目錄下面。除此之外沒有更多的要求了——可以說“沒有什么神奇的地方”。為了將代碼放在某處,大家約定成俗將視圖放置在項目(project)或應用程序(app)目錄中的名為views.py的文件中。

一個簡單的視圖

下面是一個以HTML文檔的形式返回當前日期和時間的視圖:

from django.http import HttpResponse
import datetime

def current_datetime(request):
  now = datetime.datetime.now()
  html = "<html><body>It is now %s.</body></html>" % now
  return HttpResponse(html)

讓我們來逐行解釋下上面的代碼:

首先,我們從 django.http模塊導入了HttpResponse類,以及Python的datetime庫。

接著,我們定義了current_datetime函數(shù)。它就是視圖函數(shù)。每個視圖函數(shù)都使用HttpRequest對象作為第一個參數(shù),并且通常稱之為request。

注意,視圖函數(shù)的名稱并不重要;不需要用一個統(tǒng)一的命名方式來命名,以便讓Django識別它。我們將其命名為current_datetime,是因為這個名稱能夠比較準確地反映出它實現(xiàn)的功能。

這個視圖會返回一個HttpResponse對象,其中包含生成的響應。每個視圖函數(shù)都負責返回一個HttpResponse對象。

Django使用請求和響應對象來通過系統(tǒng)傳遞狀態(tài)。

當瀏覽器向服務端請求一個頁面時,Django創(chuàng)建一個HttpRequest對象,該對象包含關于請求的元數(shù)據(jù)。然后,Django加載相應的視圖,將這個HttpRequest對象作為第一個參數(shù)傳遞給視圖函數(shù)。

每個視圖負責返回一個HttpResponse對象。視圖層,熟練掌握兩個對象即可:請求對象(request)和響應對象(HttpResponse)

二 CBV和FBV

FBV(function base views) 就是在視圖里使用函數(shù)處理請求。

    之前都是FBV模式寫的代碼,所以就不寫例子了。

CBV(class base views) 就是在視圖里使用類處理請求。

Python是一個面向對象的編程語言,如果只用函數(shù)來開發(fā),有很多面向對象的優(yōu)點就錯失了(繼承、封裝、多態(tài))。所以Django在后來加入了Class-Based-View。可以讓我們用類寫View。這樣做的優(yōu)點主要下面兩種:

  1. 提高了代碼的復用性,可以使用面向對象的技術,比如Mixin(多繼承)
  2. 可以用不同的函數(shù)針對不同的HTTP方法處理,而不是通過很多if判斷,提高代碼可讀性

如果我們要寫一個處理GET方法的view,用函數(shù)寫的話是下面這樣。

def login(request):
  if request.method == 'GET':
   return render(request, 'login.html')

如果用class-based view寫的話,就是下面這樣:

#類寫法:
class LoginView(View):
  def get(self,request):
   print('get方法執(zhí)行了')
   return render(request,'login2.html')
  def post(self,request):
    username=request.POST.get('username')
    password=request.POST.get('password')
    print('post方法執(zhí)行了')
    print(username,password)
    return HttpResponse('cg')

Django的url是將一個請求分配給可調用的函數(shù)的,而不是一個class。針對這個問題,class-based view提供了一個as_view()靜態(tài)方法(也就是類方法),調用這個方法,會創(chuàng)建一個類的實例,然后通過實例調用dispatch()方法,dispatch()方法會根據(jù)request的method的不同調用相應的方法來處理request(如get(),post()等)。到這里,這些方法和function-based view差不多了,要接收request,得到一個response返回。如果方法沒有定義,會拋出HttpResponseNotAllowed異常。

注意:使用CBV時,urls.py中也做對應的修改::

from django.conf.urls import url,include
from django.contrib import admin
from app01 import views

urlpatterns = [
  url(r'^admin/', admin.site.urls),
  url(r'^login2/$', LoginView.as_view()),

]

CBV傳參,和FBV類似,有名分組,無名分組

url寫法:無名分組的

url(r'^cv/(\d{2})/', views.Myd.as_view(),name='cv'),
 url(r'^cv/(?P<n>\d{2})/', views.Myd.as_view(name='xxx'),name='cv'),#如果想給類的name屬性賦值,前提你的Myd類里面必須有name屬性(類屬性,定義init方法來接受屬性行不通,但是可以自行研究一下,看看如何行通,意義不大),并且之前類里面的name屬性的值會被覆蓋掉

三 使用Mixin(了解)

我覺得要理解django的class-based-view(以下簡稱cbv),首先要明白django引入cbv的目的是什么。在django1.3之前,generic view也就是所謂的通用視圖,使用的是function-based-view(fbv),亦即基于函數(shù)的視圖。有人認為fbv比cbv更pythonic,竊以為不然。python的一大重要的特性就是面向對象。而cbv更能體現(xiàn)python的面向對象。cbv是通過class的方式來實現(xiàn)視圖方法的。class相對于function,更能利用多態(tài)的特定,因此更容易從宏觀層面上將項目內(nèi)的比較通用的功能抽象出來。關于多態(tài),不多解釋,有興趣的同學自己Google??傊梢岳斫鉃橐粋€東西具有多種形態(tài)(的特性)。cbv的實現(xiàn)原理通過看django的源碼就很容易明白,大體就是由url路由到這個cbv之后,通過cbv內(nèi)部的dispatch方法進行分發(fā),將get請求分發(fā)給cbv.get方法處理,將post請求分發(fā)給cbv.post方法處理,其他方法類似。怎么利用多態(tài)呢?cbv里引入了mixin的概念。Mixin就是寫好了的一些基礎類,然后通過不同的Mixin組合成為最終想要的類。

所以,理解cbv的基礎是,理解Mixin。Django中使用Mixin來重用代碼,一個View Class可以繼承多個Mixin,但是只能繼承一個View(包括View的子類),推薦把View寫在最右邊,多個Mixin寫在左邊。

四 給視圖加裝飾器使用裝飾器裝飾FBV

FBV本身就是一個函數(shù),所以和給普通的函數(shù)加裝飾器無差:

from django.shortcuts import render, HttpResponse, redirect
def wrapper(f):
  def innser(*args, **kwargs):
   print('執(zhí)行前')
   ret = f(*args, **kwargs)
   print('執(zhí)行后')
   return ret
  return innser

@wrapper
def index(request):
  print('12321')
  return render(request, 'index.html')

使用裝飾器裝飾CBV

類中的方法與獨立函數(shù)不完全相同,因此不能直接將函數(shù)裝飾器應用于類中的方法 ,我們需要先將其轉換為方法裝飾器。

Django中提供了method_decorator裝飾器用于將函數(shù)裝飾器轉換為方法裝飾器。

def wrapper(f):
  def innser(*args, **kwargs):
   print('執(zhí)行前')
   ret = f(*args, **kwargs)
   print('執(zhí)行后')
   return ret

  return innser

from django.views import View
from django.utils.decorators import method_decorator
@method_decorator(wrapper,name='get')
class LoginView(View):
  # 使用CBV時要注意,請求過來后會先執(zhí)行dispatch()這個方法,如果需要批量對具體的請求處理方法,如get,post等做一些操作的時候,這里我們可以手動改寫dispatch方法,這個dispatch方法就和在FBV上加裝飾器的效果一樣。
  # @method_decorator(wrapper)
  def dispatch(self, request, *args, **kwargs):
    # print('之前')
    ret=super().dispatch(request, *args, **kwargs)
    # print('之后')
    return ret

  # @method_decorator(wrapper)
  def get(self,request):
    print('get方法執(zhí)行了')
    return render(request,'login2.html')

  # @method_decorator(wrapper)
  def post(self,request):
    username=request.POST.get('username')
    password=request.POST.get('password')
    print('post方法執(zhí)行了')
    print(username,password)
    return HttpResponse('cg')

另外給cbv添加裝飾器的時候(先作為了解):

直接添加在dispatch里面,這樣每個函數(shù)都會執(zhí)行

from django.utils.decorators import method_decorator

@method_decorator(login_test)
def dispatch(self, request, *args, **kwargs):
res = super(IndexView, self).dispatch(request, *args, **kwargs)
return res

添加在每一個函數(shù)中

from django.utils.decorators import method_decorator

@method_decorator(login_test)
def get(self, request, *args, **kwargs):
return render(request, 'index.html')

直接添加在類上,后面的name表示只給get添加裝飾器

from django.utils.decorators import method_decorator

@method_decorator(login_test, name='get')

get是給get方法加 (以這種方式如果想給多個方法加裝飾器,需要寫多層裝飾器,因為name這個參數(shù)的值必須是個字符串,并且不能同時寫兩個方法)

@method_decorator(login_test, name='post') post是給post方法加
    class IndexView(View):
    def get(self,request):
      pass

添加裝飾器前必須導入from django.utils.decorators import method_decorator

添加裝飾器的格式必須為@method_decorator(),括號里面為裝飾器的函數(shù)名

給類添加是必須聲明name

注意csrf-token裝飾器的特殊性,在CBV模式下它只能加在dispatch上面(后面再說)

  下面這是csrf_token的裝飾器:

  @csrf_protect,為當前函數(shù)強制設置防跨站請求偽造功能,即便settings中沒有設置csrfToken全局中間件。

  @csrf_exempt,取消當前函數(shù)防跨站請求偽造功能,即便settings中設置了全局中間件。

  注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect

五 request對象官方文檔

請求相關的屬性方法(request--HttpRequest對象)

def index(request): #http相關請求信息---封裝--HttpRequest對象

  if request.method == 'GET':
    print(request.body) #獲取post請求提交過來的原始數(shù)據(jù)
    print(request.GET)  #獲取GET請求提交的數(shù)據(jù)
    # print(request.META) # 請求頭相關信息,就是一個大字典
    print(request.path) #/index/ 路徑
    print(request.path_info) #/index/ 路徑
    print(request.get_full_path()) #/index/?username=dazhuang&password=123
    
    return render(request,'index.html')
  else:
    print(request.body) # b'username=dazhuang'
    print(request.POST) #獲取POST請求提交的數(shù)據(jù)
    return HttpResponse('男賓三位,拿好手牌!')

六 response對象

與由Django自動創(chuàng)建的HttpRequest對象相比,HttpResponse對象是我們的職責范圍了。我們寫的每個視圖都需要實例化,填充和返回一個HttpResponse。

HttpResponse類位于django.http模塊中。

HttpResponse --- 回復字符串的時候來使用
render --- 回復一個html頁面的時候使用
redirect -- 重定向
  示例:
  def login(request):
    if request.method == 'GET':
      return render(request,'login.html')
    else:
      username = request.POST.get('username')
      password = request.POST.get('password')
      if username == 'taibai' and password == 'dsb':
        # return render(request,'home.html')
        return redirect('/home/') #重定向
      else:
        return HttpResponse('滾犢子,趕緊去充錢!!!')

  #首頁
  def home(request):
    return render(request,'home.html')
  
  
HttpResponse.content:響應內(nèi)容
HttpResponse.charset:響應內(nèi)容的編碼
HttpResponse.status_code:響應的狀態(tài)碼

redirect() :給瀏覽器了一個30x的狀態(tài)碼

  參數(shù)可以是:

一個模型:將調用模型的get_absolute_url() 函數(shù)

   2.一個視圖,可以帶有參數(shù):將使用urlresolvers.reverse 來反向解析名稱

   3.一個絕對的或相對的URL,將原封不動的作為重定向的位置。

   默認返回一個臨時的重定向;傳遞permanent=True 可以返回一個永久的重定向。

   示例:

​ 你可以用多種方式使用redirect() 函數(shù)。

def login(request):
  if request.method == 'GET':
   return render(request, 'login.html')
  else:
   username = request.POST.get('username')
   password = request.POST.get('password')
   if username == 'anwen@123' and password == '123':
     return redirect('/app01/home/') ##重定向到/app01/home/路徑,這也是發(fā)送了一個請求,別忘了在上面引入這個redirect類,和render、Httpresponse在一個地方引入
   else:
     return HttpResponse('登錄失敗!')


def home(request):
  return render(request, 'home.html')
#app01里的 urls.py
from django.conf.urls import url
from app01 import views
urlpatterns=[
  url(r'^$',views.login),
  url(r'^home/',views.home),
]

上面幾個文件搞好之后,我們重啟Django項目,然后登陸頁面的輸入網(wǎng)址,注意,你輸入的網(wǎng)址端口要和你啟動的django項目的端口一樣。

| 一點擊提交按鈕,你看一下network里面發(fā)送了幾個請求:兩個請求,一個是login請求,一個index請求。 |

擴展閱讀:** key兩次請求,關于301和302:   

1)301和302的區(qū)別。

301和302狀態(tài)碼都表示重定向,就是說瀏覽器在拿到服務器返回的這個狀態(tài)碼后會自動跳轉到一個新的URL地址,這個地址可以從響應的Location首部中獲取
(用戶看到的效果就是他輸入的地址A瞬間變成了另一個地址B)——這是它們的共同點。

他們的不同在于。301表示舊地址A的資源已經(jīng)被永久地移除了(這個資源不可訪問了),搜索引擎在抓取新內(nèi)容的同時也將舊的網(wǎng)址交換為重定向之后的網(wǎng)址;

302表示舊地址A的資源還在(仍然可以訪問),這個重定向只是臨時地從舊地址A跳轉到地址B,搜索引擎會抓取新的內(nèi)容而保存舊的網(wǎng)址。 SEO302好于301

2)重定向原因:

(1)網(wǎng)站調整(如改變網(wǎng)頁目錄結構);
(2)網(wǎng)頁被移到一個新地址;
(3)網(wǎng)頁擴展名改變(如應用需要把.php改成.Html或.shtml)。

這種情況下,如果不做重定向,則用戶收藏夾或搜索引擎數(shù)據(jù)庫中舊地址只能讓訪問客戶得到一個404頁面錯誤信息,訪問流量白白喪失;再者某些注冊了多個域名的網(wǎng)站,也需要通過重定向讓訪問這些域名的用戶自動跳轉到主站點等。

臨時重定向(響應狀態(tài)碼:302)和永久重定向(響應狀態(tài)碼:301)對普通用戶來說是沒什么區(qū)別的,它主要面向的是搜索引擎的機器人。

  1. A頁面臨時重定向到B頁面,那搜索引擎收錄的就是A頁面。
  2. A頁面永久重定向到B頁面,那搜索引擎收錄的就是B頁面。
  3. 用redirect可以解釋APPEND_SLASH的用法!

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 利用Python繪制創(chuàng)意中秋節(jié)月餅

    利用Python繪制創(chuàng)意中秋節(jié)月餅

    又是一年中秋至——花好月圓夜。turtle庫作為Python重要的標準庫之一,是最有價值的程序設計入門實踐庫,它是程序設計入門層面最常用的基本繪圖庫。本文將使用turtle(海龜)來繪制中秋創(chuàng)意月餅,感興趣的可以了解一下
    2022-09-09
  • 在ironpython中利用裝飾器執(zhí)行SQL操作的例子

    在ironpython中利用裝飾器執(zhí)行SQL操作的例子

    這篇文章主要介紹了在ironpython中利用裝飾器執(zhí)行SQL操作的例子,文章中以操作MySQL為例,需要的朋友可以參考下
    2015-05-05
  • Python使用RSA庫加密和解密

    Python使用RSA庫加密和解密

    這篇文章介紹了Python使用RSA庫加密和解密的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • Python字符串操作實戰(zhàn)之如何提取子字符串

    Python字符串操作實戰(zhàn)之如何提取子字符串

    這篇文章主要給大家介紹了關于Python字符串操作實戰(zhàn)之如何提取子字符串的相關資料,字符串是Python中最常用的數(shù)據(jù)類型,大家應該都不陌生,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • 如何使用Python讀取xml文件

    如何使用Python讀取xml文件

    這篇文章主要介紹了如何使用Python讀取xml文件,關于python讀取xml文章很多,但大多文章都是貼一個xml文件,然后再貼個處理文件的代碼希望這篇文章可以更通俗易懂的教如何使用python 來讀取xml 文件
    2023-04-04
  • 讓python在hadoop上跑起來

    讓python在hadoop上跑起來

    讓python在hadoop上跑起來,python如何在hadoop上跑起來?感興趣的小伙伴們可以參考一下
    2016-01-01
  • Python常用基礎模塊之os.path模塊詳解

    Python常用基礎模塊之os.path模塊詳解

    這篇文章主要介紹了Python常用基礎模塊之os.path模塊詳解,os模塊的子模塊os.path 是專門用于進行路徑操作的模塊,常用的路徑操作主要有判斷目錄是否存在、創(chuàng)建目錄、刪除目錄和遍歷目錄等,需要的朋友可以參考下
    2023-08-08
  • Python使用ChainMap實現(xiàn)組合數(shù)據(jù)魔法實例探究

    Python使用ChainMap實現(xiàn)組合數(shù)據(jù)魔法實例探究

    這篇文章主要為大家介紹了Python使用ChainMap實現(xiàn)組合數(shù)據(jù)魔法實例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • 一文弄懂10大Pandas的索引

    一文弄懂10大Pandas的索引

    索引在我們的日常生活中其實是很常見的,本文主要介紹了一文弄懂10大Pandas的索引,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-03-03
  • python基礎之貪婪模式與非貪婪模式

    python基礎之貪婪模式與非貪婪模式

    這篇文章主要介紹了python貪婪模式與非貪婪模式 ,實例分析了Python中返回一個返回值與多個返回值的方法,需要的朋友可以參考下
    2021-10-10

最新評論