<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                {% raw %} # 編寫你的第一個 Django 程序 第3部分 # 本教程上接 教程 第2部分 。我們將繼續 開發 Web-poll 應用并且專注在創建公共界面 – “視圖 (views )”。 ## 哲理 ## 在 Django 應用程序中,視圖是一“類”具有特定功能和模板的網頁。 例如,在一個博客應用程序中,你可能會有以下視圖: + 博客首頁 – 顯示最新發表的博客。 + 博客詳細頁面 – 一篇博客的獨立頁面。 + 基于年份的歸檔頁 – 顯示給定年份中發表博客的所有月份。 + 基于月份的歸檔頁 – 顯示給定月份中發表博客的所有日期。 + 基于日期的歸檔頁 – 顯示給定日期中發表的所有的博客。 + 評論功能 – 為一篇給定博客發表評論。 在我們的 poll 應用程序中,將有以下四個視圖: + Poll “index” 頁 – 顯示最新發布的民意調查。 + Poll “detail” 頁 – 顯示一項民意調查的具體問題,不顯示該項的投票結果但可以進行投票的 form 。 + Poll “results” 頁 – 顯示一項給定的民意調查的投票結果。 + 投票功能 – 為一項給定的民意調查處理投票選項。 在 Django 中,網頁及其他內容是由視圖來展現的。而每個視圖就是一個簡單的 Python 函數(或方法, 對于基于類的視圖情況下)。Django 會通過檢查所請求的 URL (確切地說是域名之后的那部分 URL)來匹配一個視圖。 平時你上網的時候可能會遇到像 “ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B” 這種如此美麗的 URL。 但是你會很高興知道 Django 允許我們使用比那優雅的 URL 模式 來展現 URL。 URL 模式就是一個簡單的一般形式的 URL - 比如: `/newsarchive/<year>/<month>/`. Django 是通過 ‘URLconfs’ 從 URL 獲取到視圖的。而 URLconf 是將 URL 模式 ( 由正則表達式來描述的 ) 映射到視圖的一種配置。 本教程中介紹了使用 URLconfs 的基本指令,你可以查閱 django.core.urlresolvers 來獲取更多信息。 ## 編寫你的第一個視圖 ## 讓我們編寫第一個視圖。打開文件 polls/views.py 并在其中輸入以下 Python 代碼 ``` from django.http import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the poll index.") ``` 在 Django 中這可能是最簡單的視圖了。為了調用這個視圖,我們需要將它映射到一個 URL – 為此我們需要配置一個URLconf 。 在 polls 目錄下創建一個名為 urls.py 的 URLconf 文檔。 你的應用目錄現在看起來像這樣 ``` polls/ __init__.py admin.py models.py tests.py urls.py views.py ``` 在 polls/urls.py 文件中輸入以下代碼: ``` from django.conf.urls import patterns, url from polls import views urlpatterns = patterns('', url(r'^$', views.index, name='index') ) ``` 下一步是將 polls.urls 模塊指向 root URLconf 。在 mysite/urls.py 中插入一個 include() 方法,最后的樣子如下所示 ``` from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', url(r'^polls/', include('polls.urls')), url(r'^admin/', include(admin.site.urls)), ) ``` 現在你在 URLconf 中配置了 index 視圖。通過瀏覽器訪問 http://localhost:8000/polls/ ,如同你在 index 視圖中定義的一樣,你將看到 “Hello, world. You’re at the poll index.” 文字。 url() 函數有四個參數,兩個必須的: regex 和 ``view``, 兩個可選的: ``kwargs``, 以及 ``name``。 接下來,來探討下這些參數的意義。 ## url() 參數: regex # regex 是 regular expression 的簡寫,這是字符串中的模式匹配的一種語法, 在 Django 中就是是 url 匹配模式。 Django 將請求的 URL 從上至下依次匹配列表中的正則表達式,直到匹配到一個為止。 需要注意的是,這些正則表達式不會匹配 GET 和 POST 參數,以及域名。 例如:針對 http://www.example.com/myapp/ 這一請求,URLconf 將只查找 myapp/``。而在 ``http://www.example.com/myapp/?page=3 中 URLconf 也僅查找 myapp/ 。 如果你需要正則表達式方面的幫助,請參閱 Wikipedia’s entry 和本文檔中的 re 模塊。 此外,O’Reilly 出版的由 Jeffrey Friedl 著的 “Mastering Regular Expressions” 也是不錯的。 但是,實際上,你并不需要成為一個正則表達式的專家,僅僅需要知道如何捕獲簡單的模式。 事實上,復雜的正則表達式會降低查找性能,因此你不能完全依賴正則表達式的功能。 最后有個性能上的提示:這些正則表達式在 URLconf 模塊第一次加載時會被編譯。 因此它們速度超快 ( 像上面提到的那樣只要查找的不是太復雜 )。 ## url() 參數: view ## 當 Django 匹配了一個正則表達式就會調用指定的視圖功能,包含一個 HttpRequest 實例作為第一個參數和正則表達式 “捕獲” 的一些值的作為其他參數。 如果使用簡單的正則捕獲,將按順序位置傳參數;如果按命名的正則捕獲,將按關鍵字傳參數值。 有關這一點我們會給出一個例子。 ## url() 參數: kwargs ## 任意關鍵字參數可傳一個字典至目標視圖。在本教程中,我們并不打算使用 Django 這一特性。 ## url() 參數: name ## 命名你的 URL ,讓你在 Django 的其他地方明確地引用它,特別是在模板中。 這一強大的功能可允許你通過一個文件就可全局修改項目中的 URL 模式。 ## 編寫更多視圖 ## 現在讓我們添加一些視圖到 polls/views.py 中去。這些視圖與之前的略有不同,因為 它們有一個參數:: ``` def detail(request, poll_id): return HttpResponse("You're looking at poll %s." % poll_id) def results(request, poll_id): return HttpResponse("You're looking at the results of poll %s." % poll_id) def vote(request, poll_id): return HttpResponse("You're voting on poll %s." % poll_id) ``` 將新視圖按如下所示的 url() 方法添加到 polls.urls 模塊中去:: ``` from django.conf.urls import patterns, url from polls import views urlpatterns = patterns('', # ex: /polls/ url(r'^$', views.index, name='index'), # ex: /polls/5/ url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'), # ex: /polls/5/results/ url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'), # ex: /polls/5/vote/ url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'), ) ``` 在你的瀏覽器中訪問 http://localhost:8000/polls/34/ 。將運行 detail() 方法并且顯示你在 URL 中提供的任意 ID 。試著訪問 http://localhost:8000/polls/34/results/ 和 http://localhost:8000/polls/34/vote/ – 將會顯示對應的結果頁及投票頁。 當有人訪問你的網站頁面如 “ /polls/34/ ” 時,Django 會加載 mysite.urls 模塊,這是因為 ROOT_URLCONF 設置指向它。接著在該模塊中尋找名為``urlpatterns`` 的變量并依次匹配其中的正則表達式。 include() 可讓我們便利地引用其他 URLconfs 。請注意 include() 中的正則表達式沒有 $ (字符串結尾的匹配符 match character) 而尾部是一個反斜杠。當 Django 解析 include() 時,它截取匹配的 URL 那部分而把剩余的字符串交由 加載進來的 URLconf 作進一步處理。 include() 背后隱藏的想法是使 URLs 即插即用。 由于 polls 在自己的 URLconf(polls/urls.py) 中,因此它們可以被放置在 “/polls/” 路徑下,或 “/fun_polls/” 路徑下,或 “/content/polls/” 路徑下,或者其他根路徑,而應用仍可以運行。 以下是當用戶訪問 “/polls/34/” 路徑時系統中將發生的事: + Django 將尋找 '^polls/' 的匹配 + 接著,Django 截取匹配文本 ("polls/") 后剩余的文本 – "34/" – 傳遞到 ‘polls.urls’ URLconf 中作進一步處理, 再將匹配 r'^(?P<poll_id>\d+)/$' 的結果作為參數傳給 detail() 視圖 ``` detail(request=<HttpRequest object>, poll_id='34') ``` poll_id='34' 這部分就是來自 (?P<poll_id>\d+) 匹配的結果。 使用括號包圍一個 正則表達式所“捕獲”的文本可作為一個參數傳給視圖函數;``?P<poll_id>`` 將會定義名稱用于標識匹配的內容; 而 \d+ 是一個用于匹配數字序列(即一個數字)的正則表達式。 因為 URL 模式是正則表達式,所以你可以毫無限制地使用它們。但是不要加上 URL 多余的部分如 .html – 除非你想,那你可以像下面這樣:: ``` (r'^polls/latest\.html$', 'polls.views.index'), ``` 真的,不要這樣做。這很傻。 ## 在視圖中添加些實際的功能 ## 每個視圖只負責以下兩件事中的一件:返回一個 HttpResponse 對象,其中包含了所請求頁面的內容, 或者拋出一個異常,例如 Http404 。剩下的就由你來實現了。 你的視圖可以讀取數據庫記錄,或者不用。它可以使用一個模板系統,例如 Django 的 – 或者第三方的 Python 模板系統 – 或不用。它可以生成一個 PDF 文件,輸出 XML , 即時創建 ZIP 文件, 你可以使用你想用的任何 Python 庫來做你想做的任何事。 而 Django 只要求是一個 HttpResponse 或一個異常。 因為它很方便,那讓我們來使用 Django 自己的數據庫 API 吧, 在 教程 第1部分 中提過。修改下 index() 視圖, 讓它顯示系統中最新發布的 5 個調查問題,以逗號分割并按發布日期排序:: ``` from django.http import HttpResponse from polls.models import Poll def index(request): latest_poll_list = Poll.objects.order_by('-pub_date')[:5] output = ', '.join([p.question for p in latest_poll_list]) return HttpResponse(output) ``` 在這就有了個問題,頁面的設計是硬編碼在視圖中的。如果你想改變頁面的外觀,就必須修改這里的 Python 代碼。因此,讓我們使用 Django 的模板系統創建一個模板給視圖用,就使頁面設計從 Python 代碼中 分離出來了。 首先,在 polls 目錄下創建一個 templates 目錄。 Django 將會在那尋找模板。 Django 的 TEMPLATE_LOADERS 配置中包含一個知道如何從各種來源導入模板的可調用的方法列表。 其中有一個默認值是 django.template.loaders.app_directories.Loader ,Django 就會在每個 INSTALLED_APPS 的 “templates” 子目錄下查找模板 - 這就是 Django 知道怎么找到 polls 模板的原因,即使我們 沒有修改 TEMPLATE_DIRS, 還是如同在 教程 第2部分 那樣。 > 組織模板 > > 我們 能夠 在一個大的模板目錄下一起共用我們所有的模板,而且它們會運行得很好。 但是,此模板屬于 polls 應用,因此與我們在上一個教程中創建的管理模板不同, 我們要把這個模板放在應用的模板目錄 (polls/templates) 下而不是項目的模板目錄 (templates) 。 我們將在 可重用的應用教程 中詳細討論我們 為什么 要這樣做。 在你剛才創建的``templates`` 目錄下,另外創建個名為 polls 的目錄,并在其中創建一個 index.html 文件。換句話說,你的模板應該是 polls/templates/polls/index.html 。由于知道如上所述的 app_directories 模板加載器是 如何運行的,你可以參考 Django 內的模板簡單的作為 polls/index.html 模板。 > 模板命名空間 > > 現在我們 也許 能夠直接把我們的模板放在 polls/templates 目錄下 ( 而不是另外創建 polls 子目錄 ) , 但它實際上是一個壞注意。 Django 將會選擇第一個找到的按名稱匹配的模板, 如果你在 不同 應用中有相同的名稱的模板,Django 將無法區分它們。 我們想要讓 Django 指向正確的模板,最簡單的方法是通過 命名空間 來確保是 他們的模板。也就是說,將模板放在 另一個 目錄下并命名為應用本身的名稱。 將以下代碼添加到該模板中: ``` {% if latest_poll_list %} <ul> {% for poll in latest_poll_list %} <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li> {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %} ``` 現在讓我們在 index 視圖中使用這個模板: ``` from django.http import HttpResponse from django.template import Context, loader from polls.models import Poll def index(request): latest_poll_list = Poll.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = Context({ 'latest_poll_list': latest_poll_list, }) return HttpResponse(template.render(context)) ``` 代碼將加載 polls/index.html 模板并傳遞一個 context 變量。 The context is a dictionary mapping template variable names to Python 該 context 變量是一個映射了 Python 對象到模板變量的字典。 在你的瀏覽器中加載 “/polls/” 頁,你應該看到一個列表,包含了在教程 第1部分 中創建的 “What’s up” 調查。而鏈接指向 poll 的詳細頁面。 ## 快捷方式: render() ## 這是一個非常常見的習慣用語,用于加載模板,填充上下文并返回一個含有模板渲染結果的 HttpResponse 對象。 Django 提供了一種快捷方式。這里重寫完整的 index() 視圖 ``` from django.shortcuts import render from polls.models import Poll def index(request): latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] context = {'latest_poll_list': latest_poll_list} return render(request, 'polls/index.html', context) ``` 請注意,一旦我們在所有視圖中都這樣做了,我們就不再需要導入 loader , Context 和 HttpResponse ( 如果你仍然保留了 detail,``resutls``, 和``vote`` 方法,你還是需要保留 HttpResponse ) 。 render() 函數中第一個參數是 request 對象,第二個參數是一個模板名稱,第三個是一個字典類型的可選參數。 它將返回一個包含有給定模板根據給定的上下文渲染結果的 HttpResponse 對象。 ## 拋出 404 異常 ## 現在讓我們解決 poll 的詳細視圖 – 該頁顯示一個給定 poll 的詳細問題。 視圖代碼如下所示:: ``` from django.http import Http404 # ... def detail(request, poll_id): try: poll = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404 return render(request, 'polls/detail.html', {'poll': poll}) ``` 在這有個新概念:如果請求的 poll 的 ID 不存在,該視圖將拋出 Http404 異常。 我們稍后討論如何設置 polls/detail.html 模板,若是你想快速運行上面的例子, 在模板文件中添加如下代碼: ``` {{ poll }} ``` 現在你可以運行了。 ## 快捷方式: get_object_or_404() ## 這很常見,當你使用 get() 獲取對象時 對象卻不存在時就會拋出 Http404 異常。對此 Django 提供了一個快捷操作。如下所示重寫 detail() 視圖: ``` from django.shortcuts import render, get_object_or_404 # ... def detail(request, poll_id): poll = get_object_or_404(Poll, pk=poll_id) return render(request, 'polls/detail.html', {'poll': poll}) ``` get_object_or_404() 函數需要一個 Django 模型類作為第一個參數以及 一些關鍵字參數,它將這些參數傳遞給模型管理器中的 get() 函數。 若對象不存在時就拋出 Http404 異常。 > 哲理 > > 為什么我們要使用一個 get_object_or_404() 輔助函數 而不是在更高級別自動捕獲 ObjectDoesNotExist 異常, 或者由模型 API 拋出 Http404 異常而不是 ObjectDoesNotExist 異常? > > 因為那樣會使模型層與視圖層耦合在一起。Django 最重要的設計目標之一 就是保持松耦合。一些控制耦合在 django.shortcuts 模塊中介紹。 還有個 get_list_or_404() 函數,與 get_object_or_404() 一樣 – 不過執行的是 filter() 而不是 get() 。若返回的是空列表將拋出 Http404 異常。 ## 編寫一個 404 ( 頁面未找到 ) 視圖 ## 當你在視圖中拋出 Http404 時,Django 將載入一個特定的視圖來處理 404 錯誤。Django 會根據你的 root URLconf ( 僅在你的 root URLconf 中;在其他任何地方設置 handler404 都無效 )中設置的 handler404 變量來查找該視圖,這個變量是個 Python 包格式字符串 – 和標準 URLconf 中的回調函數格式是一樣的。 404 視圖本身沒有什么特殊性:它就是一個普通的視圖。 通常你不必費心去編寫 404 視圖。若你沒有設置 handler404 變量,默認情況下會使用內置的 django.views.defaults.page_not_found() 視圖。或者你可以在你的模板目錄下的根目錄中 創建一個 404.html 模板。當 DEBUG 值是 False ( 在你的 settings 模塊中 ) 時, 默認的 404 視圖將使用此模板來顯示所有的 404 錯誤。 如果你創建了這個模板,至少添加些如“頁面未找到” 的內容。 一些有關 404 視圖需要注意的事項 : + 如果 DEBUG 設為 True ( 在你的 settings 模塊里 ) 那么你的 404 視圖將永遠不會被使用 ( 因此 404.html 模板也將永遠不會被渲染 ) 因為將要顯示的是跟蹤信息。 + 當 Django 在 URLconf 中不能找到能匹配的正則表達式時 404 視圖也將被調用。 編寫一個 500 ( 服務器錯誤 ) 視圖 類似的,你可以在 root URLconf 中定義 handler500 變量,在服務器發生錯誤時 調用它指向的視圖。服務器錯誤是指視圖代碼產生的運行時錯誤。 同樣,你在模板根目錄下創建一個 500.html 模板并且添加些像“出錯了”的內容。 ## 使用模板系統 ## 回到我們 poll 應用的 detail() 視圖中,指定 poll 變量后,``polls/detail.html`` 模板可能看起來這樣 : ``` <h1>{{ poll.question }}</h1> <ul> {% for choice in poll.choice_set.all %} <li>{{ choice.choice_text }}</li> {% endfor %} </ul> ``` 模板系統使用了“變量.屬性”的語法訪問變量的屬性值。 例如 `{{ poll.question }}` , 首先 Django 對 poll 對象做字典查詢。 否則 Django 會嘗試屬性查詢 – 在本例中屬性查詢成功了。 如果屬性查詢還是失敗了,Django 將嘗試 list-index 查詢。 在 `{% for %}` 循環中有方法調用: poll.choice_set.all 就是 Python 代碼 poll.choice_set.all(),它將返回一組可迭代的 Choice 對象,可以用在 `{% for %}` 標簽中。 請參閱 模板指南 來了解模板的更多內容。 ## 移除模板中硬編碼的 URLS ## 記得嗎? 在 polls/index.html 模板中,我們鏈接到 poll 的鏈接是硬編碼成這樣子的: ``` <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li> ``` 問題出在硬編碼,緊耦合使得在大量的模板中修改 URLs 成為富有挑戰性的項目。 不過,既然你在 polls.urls 模塊中的 url() 函數中定義了 命名參數,那么就可以在 url 配置中使用 `{% url %}` 模板標記來移除特定的 URL 路徑依賴: ``` <li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li> ``` > Note > > 如果 `{% url 'detail' poll.id %}` (含引號) 不能運行,但是 `{% url detail poll.id %}` (不含引號) 卻能運行,那么意味著你使用的 Djang 低于 < 1.5 版。這樣的話,你需要在模板文件的頂部添加如下的聲明:: > ``` {% load url from future %} ``` > 其原理就是在 polls.urls 模塊中尋找指定的 URL 定義。 你知道命名為 ‘detail’ 的 URL 就如下所示那樣定義的一樣:: ``` ... # 'name' 的值由 {% url %} 模板標記來引用 url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'), ... ``` 如果你想將 polls 的 detail 視圖的 URL 改成其他樣子,或許像 polls/specifics/12/ 這樣子,那就不需要在模板(或者模板集)中修改而只要在 polls/urls.py 修改就行了: ``` ... # 新增 'specifics' url(r'^specifics/(?P<poll_id>\d+)/$', views.detail, name='detail'), ... ``` ## URL 名稱的命名空間 ## 本教程中的項目只有一個應用:``polls`` 。在實際的 Django 項目中,可能有 5、10、20 或者 更多的應用。Django 是如何區分它們的 URL 名稱的呢?比如說,``polls`` 應用有一個 detail 視圖,而可能會在同一個項目中是一個博客應用的視圖。Django 是如何知道 使用 `{% url %}` 模板標記創建應用的 url 時選擇正確呢? 答案是在你的 root URLconf 配置中添加命名空間。在 mysite/urls.py 文件 (項目的 ``urls.py``,不是應用的) 中,修改為包含命名空間的定義: ``` from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', url(r'^polls/', include('polls.urls', namespace="polls")), url(r'^admin/', include(admin.site.urls)), ) ``` 現在將你的 polls/index.html 模板中原來的 detail 視圖: ``` <li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li> ``` 修改為包含命名空間的 detail 視圖: ``` <li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question }}</a></li> ``` 當你編寫視圖熟練后,請閱讀 教程 第4部分 來學習如何處理簡單的表單和通用視圖。 > 譯者:[Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html),原文:[Part 3: Views and templates](https://docs.djangoproject.com/en/1.8/intro/tutorial03/)。 > > 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 協議發布,轉載請保留作者署名和文章出處。 > > [Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html)人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。 {% endraw %}
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看