Django基礎(5:項目之Views)

上篇我們介紹 URLs 時留下了 Views 的坑沒填,沒辦法,Views 作爲整個 Django 框架的核心,跟很多模板都深刻綁定在一起

本篇就來介紹這個重中之重:Views

1.  類視圖和函數視圖

之前留下了 IndexView、DetailView、ResultsView、vote 沒寫

as_view() 代表前三個是類視圖,第四個 vote 是函數視圖,視圖就是用來實現業務功能的模塊,選用類視圖還是函數視圖視情況而定,一般顯示內容的選用類視圖,實現功能的選用函數視圖, IndexView 顯示問題索引、DetailView 顯示問題內容、ResultsView 顯示投票結果,都屬於顯示內容,所以選用類視圖。vote 實現投票功能,所以選用函數視圖

2. 函數視圖

  (1)通過函數名綁定 url

  (2)自己編寫,第一個參數 request  是固定且必要的,第二個參數是 url 裏的參數     ( '<  >'  裏包裹的) 

  (3)必須返回一個 HttpResponse 對象或者 Http404,404 是啥不用多說了

而對於類視圖,一般我們能使用通用視圖時,優先使用通用視圖,下面先說什麼是通用視圖

3. 通用視圖:

     (1)屬於類視圖

     (2)由 Django 提供 ,使用 from django.views import generic 導入

   (3)類視圖自動實現了很多功能,比如自動返回 HttpResponse 對象,爲我們能節省很多代碼和精力,但我們需要學會類視圖的使用,官方鏈接:https://docs.djangoproject.com/zh-hans/2.1/topics/class-based-views/

     (4)用類名綁定 url、用 model 屬性綁定數據模型, 用 template_name 屬性綁定頁面模板,從而實現對個模塊的關聯,注意每個類必須繼承通用視圖類 generic 的一個子類

4. 編寫 IndexView、DetailView、ResultsView、vote

from django.shortcuts import render

# Create your views here.


# 導入通用視圖
from django.views import generic
# 導入要用到的數據模型
from .models import Question, Choice
# 導入時區模塊
from django.utils import timezone
# 導入自動生成404的快捷函數,生成HttpResponse對象的快捷函數
from django.shortcuts import get_object_or_404, render
# 導入頁面重定向模塊
from django.http import HttpResponseRedirect
# 導入反向解析函數
from django.urls import reverse


# 創建索引視圖
# 必須繼承字generic的一個子類,這樣才能自動實現一些功能
# 類名直接對應urls.py裏path()的第二個參數
# 也就是URLs和Views是通過類名或者函數名進行區別綁定的
class IndexView(generic.ListView):
    # model屬性綁定數據模型
    model = Question
    # template_name屬性綁定頁面模板
    template_name = 'polls/index.html'
    # context_object_name 用於對傳給頁面模板的變量進行命名
    context_object_name = 'question_list'


# 創建問題詳情視圖
class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'

    # get_queryset()用於篩選model得到數據,結果返回給model
    def get_queryset(self):
        # 返回出版時間小於現在的
        # Question.objects.filter(pub_date__lte=timezone.now())
        # 是Django提供的數據庫API的寫法
        return Question.objects.filter(pub_date__lte=timezone.now())


# 創建投票結果視圖
class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'


# 創建投票功能視圖,是函數視圖,實現投票業務
def vote(request, question_id):
    # 獲取主鍵pk等於參數question_id的Question
    # get_object_or_404()實現:要麼獲取成功,要麼自動返回Http404
    # 第一個參數表示要獲取的數據模型
    # 第二個參數是獲取條件
    question = get_object_or_404(Question, pk=question_id)
    try:
        # 獲取投票選項
        # question.choice_set.get()是數據庫API的寫法
        # request.POST[]以字符串形式返回選擇的Choice的ID
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    # 如果在request.POST['choice']數據中沒有提供choice,POST將引發一個KeyError
    except (KeyError, Choice.DoesNotExist):
        # 如果choice不存在引發KeyError,就返回polls/detail.html頁面
        # render()用於返回HttpResponse對象
        # 第一個參數request是固定且必要的
        # 第二個參數是綁定的頁面模板
        # 第三個參數是傳到模板中的參數,是一個字典類型
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        # 選票加一
        selected_choice.votes += 1
        # 保存選票數據
        selected_choice.save()
        # 重定向到polls:results的鏈接,參數是url
        # reverse()用於對url反向解析:把名字變爲鏈接
        # 第一個參數是url的名字,路由urls.py裏面命名的
        # 第二個參數是url的參數,是一個元組類型
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

代碼中的一些說明:

       (1)代碼中的 polls/index.html、polls/detail.html、polls/results.html 等 HTML 文件是頁面,頁面模板 Templates 將在下一篇介紹,這裏先這樣寫着,留個坑下篇填

       (2)數據庫API:由Django 提供的用於訪問數據庫的接口,比如Question.objects.filter() 用於篩選,其寫法需要學習,官方文檔:https://docs.djangoproject.com/zh-hans/2.1/topics/db/queries/

       (3)request.POST['choice']以字符串形式返回選擇的 Choice 的 ID。request.POST 的值永遠是字符串,如果在 request.POST['choice'] 數據中沒有提供 choice,POST 將引發一個 KeyError 

       (4)render() 是 Views 裏面一個常用的重要函數,通過第二個參數來關聯頁面模板,第三個參數向模板傳參,實現了Views 與 Templates 的交互

       (5)重定向就是跳轉的意思,他的參數是url

       (6)reverse() 是反向解析函數:解析是把 url 用它的名字代替,參見 urls,py 裏的命名空間和 name;反向解析就是把名字還原成 url,比如對於代碼中的 'polls:results' ,根據查找 urls.py 裏的路由表,可反向解析爲  '<int:pk>/results/'  ,再根據參數 args=(question.id,) ,就解析成  'question.id/results/'  (其中 question.id 已經是具體數字),這樣就完整地實現了從 name 到 url 的反向解析,然後就可以做作爲參數傳給重定向函數  HttpResponseRedirect( ) 了

Views 基本就介紹完了,作爲 Django 核心部分,它要關聯各個模塊,從 URLs 獲取調用請求、從 Models 拿數據、從Templates  拿頁面,利用它們再根據業務邏輯生成能作爲 HTTP 響應的 HttpResponse 對象,可謂是整個框架的調度器,下篇我們介紹完 Templates 模塊,填完本篇的坑,Django 的主要流程就算是完整了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章