English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
뷰는 Django 애플리케이션에서 “타입” 웹 페이지로, 특정 기능을 제공하며 특정 템플릿을 가지고 있습니다. 예를 들어, 블로그 애플리케이션에서는 다음과 같은 뷰가 있을 수 있습니다:
블로그 홈페이지 - 최근 몇 개의 기사를 표시합니다。 “detail” 페이지에 접속하세요- 단일 항목에 대한 영구 링크 페이지입니다。 아카이브 페이지 - 지정된 연도의 각 월의 항목을 표시합니다。 월 아카이브 페이지 - 지정된 월의 모든 날짜의 모든 항목을 표시합니다。 하늘 아카이브 페이지 - 특정 날짜의 모든 항목을 표시 댓글 작업 - 특정 입력에 대한 댓글을 처리
우리의 poll 애플리케이션에서는 다음과 같은 네 가지 뷰가 있습니다:
문제의 “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)
이 새로운 뷰는 polls.urls 모듈에 다음과 같은 url() 호출을 통해 추가됩니다,polls/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(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 코드를 분리할 수 있도록 해보겠습니다. polls/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을 열고, 그에 대한 컨텍스트를 전달합니다. 컨텍스트는 템플릿 변수 이름에 매핑된 파이썬 객체의 딕셔너리입니다. URL(http://127.0.0.1:8000/polls/)결과 확인 :
이는 템플릿을 로드하고, 컨텍스트를 채우고, 템플릿을 렌더링하여 HttpResponse 객체를 반환하는 매우 일반적인 사용법입니다. Django는 이를 위한 단축 기능을 제공합니다. 완전한 index() 뷰는 다음과 같습니다. polls/views.py는 다음과 같습니다:
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를 유지하고 싶다면, 여전히 short_cut, detail, results, vote 메서드가 있습니다.
지금, 이 문제를 상세히 풀어보겠습니다 - 주어진 설문조사 질문 텍스트의 페이지를 표시합니다. 여기에 뷰 코드를 추가합니다 (polls/views.py):
django.http 를 import 하여 Http404 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와 질문이 일치하지 않습니다
를 어떻게 사용할 수 있는지 논의할 것입니다/detail.html을 수정하면 좋지만, 위의 예제를 빠르게 사용하려면 polls/templates/polls/detail.html 파일에만 다음을 포함하면 됩니다:
{{ question }}
발생합니다 404 에러, 지금 우리는 존재하지 않는 질문을 요청합니다. 예를 들어: http://127.0.0.1:8000/polls/100/결과를 다음과 같이 표시합니다:
객체가 존재하지 않을 경우 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/ 결과는 다음과 같습니다:
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 이름 정의를 정확히 볼 수 있습니다:
... # the 'name' value as called by the {% url %} template tag $, 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'), ...
이 튜토리얼 프로젝트는 하나의 애플리케이션만 있습니다 - polls. 실제 Django 프로젝트에서는 다섯, 열 개, 이십 개나 더 많은 애플리케이션이 있을 수 있습니다. 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>