国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Django中URL視圖函數(shù)的一些高級(jí)概念介紹

2020-01-04 18:01:52
字體:
供稿:網(wǎng)友
這篇文章主要介紹了Django中URL視圖函數(shù)的一些高級(jí)概念,Django是Python重多人氣框架中最為著名的一個(gè),需要的朋友可以參考下
說到關(guān)于請(qǐng)求方法的分支,讓我們來看一下可以用什么好的方法來實(shí)現(xiàn)它。 考慮這個(gè) URLconf/view 設(shè)計(jì):
 
  1. # urls.py 
  2.  
  3. from django.conf.urls.defaults import * 
  4. from mysite import views 
  5.  
  6. urlpatterns = patterns(''
  7.   # ... 
  8.   (r'^somepage/$', views.some_page), 
  9.   # ... 
  10.  
  11. # views.py 
  12.  
  13. from django.http import Http404, HttpResponseRedirect 
  14. from django.shortcuts import render_to_response 
  15.  
  16. def some_page(request): 
  17.   if request.method == 'POST'
  18.     do_something_for_post() 
  19.     return HttpResponseRedirect('/someurl/'
  20.   elif request.method == 'GET'
  21.     do_something_for_get() 
  22.     return render_to_response('page.html'
  23.   else
  24.     raise Http404() 


在這個(gè)示例中,`` some_page()`` 視圖函數(shù)對(duì)`` POST`` 和`` GET`` 這兩種請(qǐng)求方法的處理完全不同。 它們唯一的共同點(diǎn)是共享一個(gè)URL地址: `` /somepage/.``正如大家所看到的,在同一個(gè)視圖函數(shù)中對(duì)`` POST`` 和`` GET`` 進(jìn)行處理是一種很初級(jí)也很粗糙的做法。 一個(gè)比較好的設(shè)計(jì)習(xí)慣應(yīng)該是,用兩個(gè)分開的視圖函數(shù)——一個(gè)處理`` POST`` 請(qǐng)求,另一個(gè)處理`` GET`` 請(qǐng)求,然后在相應(yīng)的地方分別進(jìn)行調(diào)用。
我們可以像這樣做:先寫一個(gè)視圖函數(shù)然后由它來具體分派其它的視圖,在之前或之后可以執(zhí)行一些我們自定的程序邏輯。 下邊的示例展示了這個(gè)技術(shù)是如何幫我們改進(jìn)前邊那個(gè)簡(jiǎn)單的`` some_page()`` 視圖的:
 
  1. # views.py 
  2.  
  3. from django.http import Http404, HttpResponseRedirect 
  4. from django.shortcuts import render_to_response 
  5.  
  6. def method_splitter(request, GET=None, POST=None): 
  7.   if request.method == 'GET' and GET is not None: 
  8.     return GET(request) 
  9.   elif request.method == 'POST' and POST is not None: 
  10.     return POST(request) 
  11.   raise Http404 
  12.  
  13. def some_page_get(request): 
  14.   assert request.method == 'GET' 
  15.   do_something_for_get() 
  16.   return render_to_response('page.html'
  17.  
  18. def some_page_post(request): 
  19.   assert request.method == 'POST' 
  20.   do_something_for_post() 
  21.   return HttpResponseRedirect('/someurl/'
  22.  
  23. # urls.py 
  24.  
  25. from django.conf.urls.defaults import * 
  26. from mysite import views 
  27.  
  28. urlpatterns = patterns(''
  29.   # ... 
  30.   (r'^somepage/$', views.method_splitter, {'GET': views.some_page_get, 'POST': views.some_page_post}), 
  31.   # ... 

讓我們從頭看一下代碼是如何工作的:
    我們寫了一個(gè)新的視圖,`` method_splitter()`` ,它根據(jù)`` request.method`` 返回的值來調(diào)用相應(yīng)的視圖??梢钥吹剿鼛в袃蓚€(gè)關(guān)鍵參數(shù),`` GET`` 和`` POST`` ,也許應(yīng)該是* 視圖函數(shù)* 。如果`` request.method`` 返回`` GET`` ,那它就會(huì)自動(dòng)調(diào)用`` GET`` 視圖。 如果`` request.method`` 返回的是`` POST`` ,那它調(diào)用的就是`` POST`` 視圖。 如果`` request.method`` 返回的是其它值(如:`` HEAD`` ),或者是沒有把`` GET`` 或`` POST`` 提交給此函數(shù),那它就會(huì)拋出一個(gè)`` Http404`` 錯(cuò)誤。
    在URLconf中,我們把`` /somepage/`` 指到`` method_splitter()`` 函數(shù),并把視圖函數(shù)額外需要用到的`` GET`` 和`` POST`` 參數(shù)傳遞給它。
    最終,我們把`` some_page()`` 視圖分解到兩個(gè)視圖函數(shù)中`` some_page_get()`` 和`` some_page_post()`` 。這比把所有邏輯都擠到一個(gè)單一視圖的做法要優(yōu)雅得多。
    注意,在技術(shù)上這些視圖函數(shù)就不用再去檢查`` request.method`` 了,因?yàn)閌` method_splitter()`` 已經(jīng)替它們做了。 (比如,`` some_page_post()`` 被調(diào)用的時(shí)候,我們可以確信`` request.method`` 返回的值是`` post`` 。)當(dāng)然,這樣做不止更安全也能更好的將代碼文檔化,這里我們做了一個(gè)假定,就是`` request.method`` 能象我們所期望的那樣工作。
現(xiàn)在我們就擁有了一個(gè)不錯(cuò)的,可以通用的視圖函數(shù)了,里邊封裝著由`` request.method`` 的返回值來分派不同的視圖的程序。關(guān)于`` method_splitter()`` 就不說什么了,當(dāng)然,我們可以把它們重用到其它項(xiàng)目中。
然而,當(dāng)我們做到這一步時(shí),我們?nèi)匀豢梢愿倪M(jìn)`` method_splitter`` 。從代碼我們可以看到,它假設(shè)`` Get`` 和`` POST`` 視圖除了`` request`` 之外不需要任何其他的參數(shù)。那么,假如我們想要使用`` method_splitter`` 與那種會(huì)從URL里捕捉字符,或者會(huì)接收一些可選參數(shù)的視圖一起工作時(shí)該怎么辦呢?
為了實(shí)現(xiàn)這個(gè),我們可以使用Python中一個(gè)優(yōu)雅的特性 帶星號(hào)的可變參數(shù) 我們先展示這些例子,接著再進(jìn)行解釋
 
  1. def method_splitter(request, *args, **kwargs): 
  2.   get_view = kwargs.pop('GET', None) 
  3.   post_view = kwargs.pop('POST', None) 
  4.   if request.method == 'GET' and get_view is not None: 
  5.     return get_view(request, *args, **kwargs) 
  6.   elif request.method == 'POST' and post_view is not None: 
  7.     return post_view(request, *args, **kwargs) 
  8.   raise Http404 

這里,我們重構(gòu)method_splitter(),去掉了GET和POST兩個(gè)關(guān)鍵字參數(shù),改而支持使用*args和和**kwargs(注意*號(hào)) 這是一個(gè)Python特性,允許函數(shù)接受動(dòng)態(tài)的、可變數(shù)量的、參數(shù)名只在運(yùn)行時(shí)可知的參數(shù)。 如果你在函數(shù)定義時(shí),只在參數(shù)前面加一個(gè)*號(hào),所有傳遞給函數(shù)的參數(shù)將會(huì)保存為一個(gè)元組. 如果你在函數(shù)定義時(shí),在參數(shù)前面加兩個(gè)*號(hào),所有傳遞給函數(shù)的關(guān)鍵字參數(shù),將會(huì)保存為一個(gè)字典
例如,對(duì)于這個(gè)函數(shù)
 
  1. def foo(*args, **kwargs): 
  2.   print "Positional arguments are:" 
  3.   print args 
  4.   print "Keyword arguments are:" 
  5.   print kwargs 


看一下它是怎么工作的
 
  1. >>> foo(1, 2, 3) 
  2. Positional arguments are: 
  3. (1, 2, 3) 
  4. Keyword arguments are: 
  5. {} 
  6. >>> foo(1, 2, name='Adrian', framework='Django'
  7. Positional arguments are: 
  8. (1, 2) 
  9. Keyword arguments are: 
  10. {'framework''Django''name''Adrian'


回過頭來看,你能發(fā)現(xiàn)我們用method_splitter()和*args接受**kwargs函數(shù)參數(shù)并把它們傳遞到正確的視圖。any 但是在我們這樣做之前,我們要調(diào)用兩次獲得參數(shù)kwargs.pop()GETPOST,如果它們合法的話。 (我們通過指定pop的缺省值為None,來避免由于一個(gè)或者多個(gè)關(guān)鍵字缺失帶來的KeyError)
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 温泉县| 呈贡县| 南召县| 如皋市| 阿克苏市| 郎溪县| 南涧| 四会市| 鸡东县| 白水县| 清流县| 阳山县| 科尔| 泊头市| 三门峡市| 巴楚县| 崇州市| 百色市| 黔南| 沽源县| 寿阳县| 华阴市| 林甸县| 南阳市| 塔城市| 伊春市| 东乡县| 灵武市| 无为县| 涞源县| 四子王旗| 邓州市| 利川市| 开江县| 蓬安县| 察隅县| 弥渡县| 平阳县| 若尔盖县| 岳西县| 广宗县|