frist Django app — 3、 View

 前面已經說過了Django中model的一些用法,包括orm,以及操做的api,接下來就是搭一些簡單的界面學習view——Django中的view。主要介紹如下兩個方面:html

  • url映射
  • 請求處理
  • 模板文件

url映射和請求處理共同構成了MVC中的C——controller,這裏面涉及了url的寫法(主要是正則表達式),接收頁面傳遞過來的參數。在Django中可使用template來進行頁面渲染,這樣能夠直接使用傳遞過來的數據。正則表達式

url映射

這裏緊接着上一篇的工程完善polls項目,polls網站首頁顯示最近的問題列表,還能夠查看某一個問題的詳情,能夠進一步查看調查問題的結果。進行投票django

  • index:顯示最近的問題列表
  • detail:查看調查問題詳細信息
  • result:顯示某一個問題的結果
  • vote:對問題某一個答案進行投票

以上的四個功能咱們分別用四個頁面,編輯polls/urls,py後端

from django.conf.urls import url
from . import views

app_name = 'polls'
urlpatterns = [
    url(r'^$', views.index, name = 'index'),
    url(r'^(?P<question_id>[0-9]+)/detail/$', views.detail, name = 'detail'),
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name = 'results'),
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name = 'vote'),
]

name:url規則的名稱,可在模板中引用api

app_name:定義url的命名空間,命名空間的做用就是防止name重名app

請求處理

編輯polls/views.py學習

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404
from models import Question

# Create your views here.
def index(request):
   # 查詢最新的五條Question,- 表示降序排列 latest_question_list
= Question.objects.order_by('-publ_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context) def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question}) def results(request, question_id): return HttpResponse("result:question id is %s" % question_id) def vote(request, question_id): return HttpResponse("vote:question id is %s" % question_id)

views.py處理經過urls.py分發過來的請求,好比上面最後一個vote中,很簡單直接返回一個HttpResponse對象,其實全部的views處理都是返回該HttpResponse對象,包括使用可以render方法的時候優化

  • 直接返回HttpResonse
  • 經過調用render,將數據渲染到templates再返回HttpResponse

get_object_or_404:獲取一個Question對象,若是沒有就拋出Http404 Exception,這是通過優化後的代碼,原本是本身手動查找一個對象,本身判斷對象是否存在,不存在再raise Exception,改進以後下降了model和view之間的耦合,這樣view再也不依賴model層的具體實現,達到解耦的目的。 網站

模板文件

在mysite/polls下新建兩級目錄mysite/polls/templates/polls,templates是固定的,polls是APP名稱,而後在mysite/polls/templates/polls目錄下新建一個index.html文件——也就是模板文件編碼

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="{% url 'polls.detail' question.id %}">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

這裏有幾點先說明一下:

templates/polls目錄

在settings.py裏面有關於templates的配置

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

BACKEND:後端用的模板引擎django.template.backends.django.DjangoTemplates

DIRS:模板的位置也就是說不必定要放在約定的目錄裏面,可是建議最好放在每一個APP名稱的目錄下,避免多個APP的狀況下有模板名稱相同的時候Django分不清

APP_DIRS:爲true的時候DjangoTemplates會搜索app所在目錄下的模板即polls/templates/polls

因此上面咱們放在了默認目錄

template語法

在Djang的模板裏面包含普通的html代碼和模板代碼,好比if-else,for,dotted語法(訪問數據)等。這裏先介紹一些基本的,關於html很少說。

  • 模板代碼使用普通{%%}包圍,還有好比{%url%}語法
  • {{模板中的數據}}
  • {%if %} {%else %} {%endif %}
  • {%for %} {%endfor%}
  • latest_question_list爲views.py傳遞過來的參數,可使用點語法訪問數據,支持的數據格式有值傳遞和引用(包括:list,dic,tuple,對象屬性,對象方法(沒有其餘參數,必須有返回值)),使用點語法的時候Django搜索參數的順序是:字典,對象屬性,對象方法,list

url命名空間

<li><a href="{% url 'polls.detail' question.id %}">{{ question.question_text }}</a></li>

在urls.py文件中經過申明一個全局變量app_name就是url的命名空間,在{%url %}語法中就可使用app_name+name 的方式引用url,好比‘polls.detail’說明使用哪個url匹配,question_id爲傳遞給url匹配的參數

 

總結

除了學習Django的基本知識,還學習(膜拜)了Django的精巧設計,鬆耦合

  • Django對獲取單個對象的時候Http404異常作了封裝,解耦model和view
  • 使用{%url %}語法不須要將url硬編碼在template文件中,達到和url映射解耦的目的

 


 

完整代碼

http://pan.baidu.com/s/1kUFv5lH

相關文章
相關標籤/搜索