一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Django中URL視圖函數的一些高級概念介紹

Django中URL視圖函數的一些高級概念介紹

2020-07-24 11:40Python教程網 Python

這篇文章主要介紹了Django中URL視圖函數的一些高級概念,Django是Python重多人氣框架中最為著名的一個,需要的朋友可以參考下

說到關于請求方法的分支,讓我們來看一下可以用什么好的方法來實現它。 考慮這個 URLconf/view 設計:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# urls.py
 
from django.conf.urls.defaults import *
from mysite import views
 
urlpatterns = patterns('',
  # ...
  (r'^somepage/$', views.some_page),
  # ...
)
 
# views.py
 
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render_to_response
 
def some_page(request):
  if request.method == 'POST':
    do_something_for_post()
    return HttpResponseRedirect('/someurl/')
  elif request.method == 'GET':
    do_something_for_get()
    return render_to_response('page.html')
  else:
    raise Http404()

在這個示例中,`` some_page()`` 視圖函數對`` POST`` 和`` GET`` 這兩種請求方法的處理完全不同。 它們唯一的共同點是共享一個URL地址: `` /somepage/.``正如大家所看到的,在同一個視圖函數中對`` POST`` 和`` GET`` 進行處理是一種很初級也很粗糙的做法。 一個比較好的設計習慣應該是,用兩個分開的視圖函數——一個處理`` POST`` 請求,另一個處理`` GET`` 請求,然后在相應的地方分別進行調用。

我們可以像這樣做:先寫一個視圖函數然后由它來具體分派其它的視圖,在之前或之后可以執行一些我們自定的程序邏輯。 下邊的示例展示了這個技術是如何幫我們改進前邊那個簡單的`` some_page()`` 視圖的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# views.py
 
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render_to_response
 
def method_splitter(request, GET=None, POST=None):
  if request.method == 'GET' and GET is not None:
    return GET(request)
  elif request.method == 'POST' and POST is not None:
    return POST(request)
  raise Http404
 
def some_page_get(request):
  assert request.method == 'GET'
  do_something_for_get()
  return render_to_response('page.html')
 
def some_page_post(request):
  assert request.method == 'POST'
  do_something_for_post()
  return HttpResponseRedirect('/someurl/')
 
# urls.py
 
from django.conf.urls.defaults import *
from mysite import views
 
urlpatterns = patterns('',
  # ...
  (r'^somepage/$', views.method_splitter, {'GET': views.some_page_get, 'POST': views.some_page_post}),
  # ...
)

讓我們從頭看一下代碼是如何工作的:

    我們寫了一個新的視圖,`` method_splitter()`` ,它根據`` request.method`` 返回的值來調用相應的視圖。可以看到它帶有兩個關鍵參數,`` GET`` 和`` POST`` ,也許應該是* 視圖函數* 。如果`` request.method`` 返回`` GET`` ,那它就會自動調用`` GET`` 視圖。 如果`` request.method`` 返回的是`` POST`` ,那它調用的就是`` POST`` 視圖。 如果`` request.method`` 返回的是其它值(如:`` HEAD`` ),或者是沒有把`` GET`` 或`` POST`` 提交給此函數,那它就會拋出一個`` Http404`` 錯誤。

    在URLconf中,我們把`` /somepage/`` 指到`` method_splitter()`` 函數,并把視圖函數額外需要用到的`` GET`` 和`` POST`` 參數傳遞給它。

    最終,我們把`` some_page()`` 視圖分解到兩個視圖函數中`` some_page_get()`` 和`` some_page_post()`` 。這比把所有邏輯都擠到一個單一視圖的做法要優雅得多。

    注意,在技術上這些視圖函數就不用再去檢查`` request.method`` 了,因為`` method_splitter()`` 已經替它們做了。 (比如,`` some_page_post()`` 被調用的時候,我們可以確信`` request.method`` 返回的值是`` post`` 。)當然,這樣做不止更安全也能更好的將代碼文檔化,這里我們做了一個假定,就是`` request.method`` 能象我們所期望的那樣工作。

現在我們就擁有了一個不錯的,可以通用的視圖函數了,里邊封裝著由`` request.method`` 的返回值來分派不同的視圖的程序。關于`` method_splitter()`` 就不說什么了,當然,我們可以把它們重用到其它項目中。

然而,當我們做到這一步時,我們仍然可以改進`` method_splitter`` 。從代碼我們可以看到,它假設`` Get`` 和`` POST`` 視圖除了`` request`` 之外不需要任何其他的參數。那么,假如我們想要使用`` method_splitter`` 與那種會從URL里捕捉字符,或者會接收一些可選參數的視圖一起工作時該怎么辦呢?

為了實現這個,我們可以使用Python中一個優雅的特性 帶星號的可變參數 我們先展示這些例子,接著再進行解釋

?
1
2
3
4
5
6
7
8
def method_splitter(request, *args, **kwargs):
  get_view = kwargs.pop('GET', None)
  post_view = kwargs.pop('POST', None)
  if request.method == 'GET' and get_view is not None:
    return get_view(request, *args, **kwargs)
  elif request.method == 'POST' and post_view is not None:
    return post_view(request, *args, **kwargs)
  raise Http404

這里,我們重構method_splitter(),去掉了GET和POST兩個關鍵字參數,改而支持使用*args和和**kwargs(注意*號) 這是一個Python特性,允許函數接受動態的、可變數量的、參數名只在運行時可知的參數。 如果你在函數定義時,只在參數前面加一個*號,所有傳遞給函數的參數將會保存為一個元組. 如果你在函數定義時,在參數前面加兩個*號,所有傳遞給函數的關鍵字參數,將會保存為一個字典

例如,對于這個函數

?
1
2
3
4
5
def foo(*args, **kwargs):
  print "Positional arguments are:"
  print args
  print "Keyword arguments are:"
  print kwargs

看一下它是怎么工作的

?
1
2
3
4
5
6
7
8
9
10
>>> foo(1, 2, 3)
Positional arguments are:
(1, 2, 3)
Keyword arguments are:
{}
>>> foo(1, 2, name='Adrian', framework='Django')
Positional arguments are:
(1, 2)
Keyword arguments are:
{'framework': 'Django', 'name': 'Adrian'}

回過頭來看,你能發現我們用method_splitter()和*args接受**kwargs函數參數并把它們傳遞到正確的視圖。any 但是在我們這樣做之前,我們要調用兩次獲得參數kwargs.pop()GETPOST,如果它們合法的話。 (我們通過指定pop的缺省值為None,來避免由于一個或者多個關鍵字缺失帶來的KeyError)

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 99ri在线精品视频 | 日本护士撒尿xxxx18 | 骚b小说| 美女林柏欣21p人体之仓之梦 | 欧美日韩国产在线人成 | 明星ai人脸替换脸忘忧草 | 亚洲美色综合天天久久综合精品 | 91啪在线观看国产在线 | 久久青草费线频观看国产 | 国产综合亚洲欧美日韩一区二区 | 男人女人日皮 | 免费视频观看 | ckinese中国男同gay男男 | 久久99精品久久久久久园产越南 | 日本肉体xxxx69xxxx | 四虎影视永久在线观看 | 饭冈加奈子乳喷cead144 | 呜呜别塞了啊抽插 | 欧美人妖大啪啪 | 欧美精品一区二区三区久久 | 好大~好爽~再进去一点 | 动漫美女被吸乳羞羞小说 | 美女的让男人桶爽网站 | 青青青青久久国产片免费精品 | 视频一区二区三区在线 | xxnx日本免费护士 | 成年性香蕉漫画在线观看 | 女人国产香蕉久久精品 | 夫妻性生活一级黄色片 | 高跟丝袜人妖sissy露出调教 | 精品日韩一区 | 成人性爱视频在线观看 | 91制片厂 果冻传媒 天美传媒 | 无码国产成人777爽死在线观看 | 国产精品久久国产精品99盘 | 亚洲国产成人精品无码区APP | 国产成人啪精品午夜在线播放 | 日韩高清在线观看 | 国产日韩欧美在线一二三四 | 国产日韩在线 | 丰满肥臀风间由美357在线 |