使用Django+React学习编程基础(9): Django教程(投票应用程序第4-2部分)
[前回] 学习编程基础:Django+React (8):Django教程(投票应用程序第4-1部分)
首先
以上是Django官方教程的第4-2部分。
上一节中,我们为应用添加了表单。
本节主要介绍通用视图。
Django 应用创建(第四部分-2):投票应用
这次的内容
- 汎用ビューを使用
使用通用视图
-
- 汎用ビューとは
よくあるパターンを抽象化し、Pythonコードすら書かずアプリを書き上げられる
コードが少ないのはいいことだけど、どうやって実現する?
投票アプリを汎用ビューシステムに変換し、 コードをばっさり捨てる
変換は数ステップ
URLconfを変換
古い不要なビューを削除
新しいビューにDjango汎用ビューを設定
コードを入れ換える
Djangoアプリを書く場合、最初から自分の問題解決に適している汎用ビューを使用
チュートリアルでは、説明のため途中から汎用ビューに変更
修改URLconf
-
- 汎用ビュー向けにquestion_idをpkに変更
汎用ビューの場合、URLからpkという名前でプライマリキーをキャプチャし、汎用ビューに渡しているため
2つ目と3つ目のパス文字列に該当するパターン名をからに変更
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
修正视图
-
- 古いindex、detail、resultsのビューを削除
-
- 代わりに、Djangoの汎用ビューを使用
ListView汎用ビュー
オブジェクトのリストを表示するという概念を抽象化
DetailView汎用ビュー
あるタイプのオブジェクトの詳細ページを表示するという概念を抽象化
汎用ビューとモデルのマッピング
model属性を使用
汎用ビューのテンプレート
デフォルトで、 汎用ビューが使用するテンプレート
DetailView汎用ビューの場合
/_detail.html
例えば、polls/question_detail.html
ListView汎用ビューの場合、
/_list.html
結果ビューResultViewと詳細ビューDetailViewは、同じDetailView汎用ビューを使用
template_name属性を指定し、異なる見た目にレンダリング可能
自動生成のデフォルトテンプレート名ではなく、指定テンプレート名を使うよう Djangoに伝える
索引ビューIndexViewは、ListView汎用ビューを使用
template_name属性を指定し、polls/index.htmlテンプレートを使用するように指示
テンプレートに渡すコンテキスト変数
DetailViewに、questionというコンテキスト変数が自動的に渡される
理由は、モデルQuestionとマッピングされているため、Djangoがコンテキスト変数にふさわしい名前を決めてくれる
ListViewに、question_listというコンテキスト変数が自動的に渡される
上書きするには、context_object_name属性を使用
代替アプローチとして、テンプレート名をデフォルトのコンテキスト変数名と一致させることもできる
ただし、使用したいコンテキスト変数名をDjangoに伝えたほうが簡単
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from .models import Choice, Question
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
def vote(request, question_id):
... # same as above, no changes needed.
运行服务器,验证转换为通用视图基础的投票应用。
- VS Codeターミナルで、仮想環境をアクティベート
C:\kanban\pollsite>..\venv\.venv\Scripts\activate
- 開発サーバーを起動
(venv) C:\kanban\pollsite>python manage.py runserver
![image.png](https://cdn.silicloud.com/blog-img/blog/img/657d8cc3913a08637a6d1819/19-0.png)
点击问题。
![image.png](https://cdn.silicloud.com/blog-img/blog/img/657d8cc3913a08637a6d1819/21-0.png)
我将试试投票。
结束时
我将Django应用程序更新为通用视图。敬请期待下一篇。