English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Django ファーストステップ-ビュー

ビューはDjangoアプリケーション内のウェブページ「タイプ」で、特定の機能を提供し、特定のテンプレートを持っています。例えば、ブログのアプリケーションでは、以下のようなビューが存在するかもしれません:

ブログのホームページ - 最後の数つの記事を表示します。 「detail」ページに入ります- 単一のプロジェクトの永続リンクページです。 アーカイブページ - 指定された年の各月のエントリを表示します。 月アーカイブページ - 指定された月の各日のすべての項目を表示します。 天アーカイブページ - 特定の日付のすべてのエントリを表示します。 コメント操作 - 特定の入力に対するコメントの処理を行います。

私たちのpollアプリケーションには、以下の4つのビューがあります:

問題の「index」ページ- 最後のいくつかの問題を表示します。 問題の「detail」ページ - 問題のテキストを表示し、結果はありませんが投票するためのフォームがあります。 問題の「results」ページ - 特定の問題の結果を表示します。 投票操作 - 特定の問題に対する投票の処理を行います。

Djangoでは、ウェブページや他のコンテンツはビューによって提供されます。各ビューはシンプルなPython関数で表されます(または、クラスベースのビュー)。Djangoは、ユーザーがリクエストしたURLの一部(正確にはドメインの後のURLの一部)を考慮して、ビューを選択します。

URLパターンは単純なURLの一般的な形式です。 - 例えば:/newsarchive/<year>/<month>/.

さらにビューを書きます。

今、pollsにビューを追加しましょう。/views.py。これらのビューは少し異なります。なぜなら、彼らにはパラメータが必要だからです:

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)
def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

これらの新しいビューは以下のurl()呼び出しにpolls.urlsモジュールに追加されています。/urls.pyファイルの以下のコードが示されています:

from django.conf.urls import url
from django.conf.urls import url
app_name = 'polls'
 # ex: /polls/
    urlpatterns = [
 # ex: /polls/5/
    $, views.results, name='results'),-9]+)/$, views.index, name='index'),
 # ex: /polls/5/$, views.detail, name='detail'),/
    $, views.results, name='results'),-9]+)/$, views.detail, name='detail'),/results
 # ex: /polls/5/vote/
    $, views.results, name='results'),-9]+)/vote/$, views.vote, name='vote'),
]

ブラウザで「/polls/34/」。それはdetail()メソッドを実行し、提供されたURLの内容を表示します。もう一度「/polls/34/$, views.detail, name='detail'),/および「/polls/34/vote/」を表示し、プレースホルダー結果と投票ページを表示します。

include()を使うことで、プラグインやURLを簡単に含めることができます。なぜなら、pollsは独自のURL設定(polls/urls.py)に配置できます。/polls/または「/fun_polls/または、/content/polls/アプリケーションがルートの他のどのパスでも動作する。

以下は、ユーザーが「/polls/34/」のシステムで何が起こるか:

次に、Djangoは'^polls/)を取り除きます 次に、Djangoはマッチングされたテキスト("polls/"

并发送残りのテキスト – "34/" – 'polls.urls'URL設定にマッチングされたものをさらに処理するために使用されます r'^(?P<question_id>[0-9]+)/$'を使用してdetail()ビューを呼び出します、以下のように:

detail(request=<HttpRequest object>, question_id='34')

question_id='34''は、(?P<question_id>[0-9]+)の一部を、周囲のパターンブラケットで「キャプチャ」して、それをパターンとして識別するためにパラメータとして視覚関数に渡します;  ?P<question_id> は、マッチングされたパターンを識別するために使用される名前を定義し、[0-9]+ 正規表現は数字のシーケンス(数字一つ)をマッチングします。

URLパターンは正規表現であり、制限なく何かを行うことができます。また、.htmlにURLを追加する必要もありません。必要であれば、以下のようにできます:

url(r'^polls/latest\.html$', views.index),

ビュー機能を実装します

各ビューは以下の二つのうちの一つを担当します:リクエストされたページ内容を含むHttpResponseオブジェクトを返す、またはHTTPなどの例外をスローする 404。 pollsを変更します/views.pyファイルのコードは以下の通りです:

from django.http import HttpResponse
from .models import Question
def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    output = ', '.join([q.question_text for q in latest_question_list])
    return HttpResponse(output)
# 残りのビュー(detail、results、vote)は変更しない

ここに問題があります、以下の方法で:ウェブデザインはビューに硬コードされています。ページの見た目を変更するには、このPythonコードを編集する必要があります。したがって、Djangoテンプレートシステムを使用して、ビューがテンプレートを作成できるようにPythonコードを分離するようにしましょう。/templates/polls/index.html 次のコード:

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

现在我们来更新首页视图 polls/views.pyは以下のテンプレート(コード)を使用しています:

from django.http import HttpResponse
from django.template import loader
from .models import Question
def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))

该代码加载模板调用polls/index.htmlにアクセスし、そのコンテキストを渡します。コンテキストは、Pythonオブジェクトをテンプレート変数名にマッピングする辞書です。URL(http://127.0.0.1:8000/polls/)查看结果 :

ショートカット: render()

这是一个非常习惯的用法来加载模板,填充上下文并渲染模板的结果,然后返回一个HttpResponse对象。Django提供了一个捷径。下面是完整的index() 视图,改写polls/views.pyの内容は以下の通りです:

from django.shortcuts import render
from .models import Question
def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

请注意,当在各个视图中做到这一点时,我们不再需要导入加载器和HttpResponse对象(如果仍然需要保留HttpResponse,则仍有detail、results和vote方法。

発生404错误

现在,让我们详细解决这个问题视图 - 表示给定民意调查问题文本的页面。在此处添加视图代码(polls/views.py):

from django.http import Http404
from django.shortcuts import render
from .models import Question
# ...
def detail(request, question_id):
    try:
        question = Question.objects.get(pk=question_id)
    except Question.DoesNotExist:
        raise Http404("Question does not exist")
    return render(request, 'polls/detail.html', {'question': question})

注:このビューは HTTP404例外について説明します。リクエストIDと問題が一致しない場合に発生します。

私たちは polls/detail.html は後で修正するかもしれませんが、上記の例をすぐに使用する場合は polls/templates/polls/detail.html ファイルには以下を含めます:


   {{ question }}


発生 404 エラー、現在は存在しない問題をリクエストしています、例えば:http://127.0.0.1:8000/polls/100/、以下の結果が表示されます:

ショートカット: get_object_or_404()

オブジェクトが存在しない場合の非常に一般的な使い方として get() を使用して HTTP404エラー。Django は簡単な方法を提供しています。以下は detail() ビューです、polls/views.py を改写:

from django.shortcuts import get_object_or_404, render
from .models import Question
# ...
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

get_object_or_404() 関数が、Django モデルを最初の引数として受け取り、任意のキーワード引数を指定して、モデルの管理 get() 関数に渡します。

オブジェクトが存在しない場合に HTTP404。

get_list_or_404() 関数が、get_object_or_404()- filter() メソッドではなく get() メソッドを使用することで、リストが空の場合に HTTP404。

テンプレートシステムを使用して

私たちの polls アプリケーションの detail() ビューに戻ります。この polls/detail.html テンプレートはこんな感じです:

<h1{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>/li>
{% endfor %}
</ul>


テンプレートシステムは点クエリ構文を使用して変数属性にアクセスします。この例では{{question.question_text }}、最初のDjangoはquestionオブジェクトの辞書を検索します。見つからない場合、属性クエリを試みます – 属性クエリが失敗すると、リストインデックスクエリを試みます。
上記のコードをテストするには、ブラウザで以下を開いてください:http://127.0.0.1:8000/polls/5/ 以下の結果が得られます:

テンプレートの硬コーディングされたURLを削除します

pollsで変更を行う際には、以下のように覚えておいてください:/index.htmlは問題にリンクしており、リンクの硬コーディングされた部分は以下のようです:

  <li><a href="/polls/{{question.id}}/">{{question.question_text}}</a></li>

この硬コード化、緊密なコードの問題は、プロジェクトのURLを変更する際に多くのテンプレートに依存するところにあります。ただし、polls.urlsモジュールで名前パラメータurl()関数を定義しているため、{% url %}テンプレートタグを使用して、URL設定で特定のURLパスの依存関係を削除できます:

  <li><a href="{etail'question.id%}">{{question.question_text}}</a></li>

この方法は、polls.urlsモジュールで検索するURLの定義に指定することで実現されます。'detail'のURL名の定義が以下のように正確に見られます:

  ...
# 'name'値は{% url %}テンプレートタグで呼ばれます
$, views.results, name='results'),-9]+)/$, views.index, name='index'),
...

投票詳細ビューのURLを他に変更したい場合、例えばpolls/specifics/12/ テンプレート(またはtemplates)で変更するには、polls/urls.pyを変更する:

  ...
# added the word 'specifics'
url(r'^specifics',/(?P<question_id>[0-9]+)/$, views.index, name='index'),
...

命名空間URL名

このチュートリアルプロジェクトにはアプリケーションが1つだけあります - polls。実際のDjangoプロジェクトでは、5つ、10つ、20つやそれ以上のアプリケーションがあるかもしれません。Djangoは、これらのURLの名前をどのように区別しますか?例えば、投票アプリケーションには詳細ビューがありますので、同じプロジェクトのブログにも同じアプリケーションがあるかもしれません。どのようにして{% url %}テンプレートタグを使ってDjangoに、どのアプリケーションがそのビューを持っているかを教えますか?

答えは、命名空間をURLconfに追加することです。polls/urls.pyファイル、進む、アプリケーション名の設定、アプリケーション命名空間を開く polls/urls.py:

from django.conf.urls import url
from django.conf.urls import url
from . import views
app_name = 'polls'
    urlpatterns = [
    $, views.results, name='results'),-9]+)/$, views.index, name='index'),
    $, views.results, name='results'),-9]+)/$, views.detail, name='detail'),/results
    $, views.results, name='results'),-9]+)/vote/$, views.vote, name='vote'),
]

今、pollsを変更します/index.html テンプレート、pollsを開きます/templates/polls/index.html ファイルに以下のコードを追加します:

  <li><a href="{etail'question.id%}">{{question.question_text}}</a></li>

detail ナームスペースのビューに指し示すように設定し、pollsを開きます/templates/polls/index.html ファイルは以下の通りです:

  <li><a href="{olls:detail'question.id%}">{{question.question_text}}</a></li>