投票アプリケーション-クラスビューに変更
20116 ワード
URLConf符号化
voting/urls.pyファイルの変更
...
urlpatterns = [
# /voting/
path('', views.IndexView.as_view(), name='index'),
# /voting/99
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
# /voting/99/results/
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
# /voting/99/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
Viewエンコーディング
関数ビュー->クラスビュー
voting/views.pyファイルの変更
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 voting.models import Question, Choice
# ListView를 상속받는 경우 객체가 들어있는 리스트를 구성해서
# 이를 컨텍스트 변수로 템플릿 시스템으로 넘겨주면 되는데
# 이 리스트가 모든 테이블의 레코드 구성이라면 모델 클래스만 지정
# 아니면 get_queryset() 메소드 오버라이딩하여 원하는 리스트 구성
class IndexView(generic.ListView):
template_name = 'voting/index.html'
# 컨텍스트 변수명 지정
context_object_name = 'latest_question_list'
def get_queryset(self):
# 최근 생성된 질문 5개 반환
return Question.objects.order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
# Question 테이블로부터 특정 레코드를 가져와 컨텍스트 변수 구성
# 컨텍스트 변수명은 디폴트 값을 사용하고
# object와 모델명 소문자인 quesiton 둘 다 가능
model = Question
template_name = 'voting/detail.html'
class ResultsView(generic.DetailView):
# Choice가 아닌 Question 객체를 넘겨준다.
# Question 객체를 구해서 해당 객체와 FK로 연결된 Choice를 구한다.
# 이 로직은 results.html 템플릿 파일에서
# question.choice_set.all() 구문으로 구현되어 있다.
model = Question
template_name = 'voting/results.html'
def vote(request, question_id):
# Choice 테이블을 검색한다. request.POST는 제출된 폼의 데이터를 담고 있는
# 객체로서 key로 그 값을 구할 수 있다.
# request.POST['choice']는 폼 데이터에서 키가 'choice'에 해당하는 값인
# choice.id를 스트링으로 리턴한다.
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
# 'choice'라는 키가 없으면 KeyError 익셉션 발생
# 검색 조건에 맞는 객체가 없으면 Choice.DoesNotExist 익셉션 발생
except (KeyError, Choice.DoseNotExist):
# 익셉션이 발생하면 render() 함수에 의해 question과 error_message
# 컨텍스트 변수를 detail.html 템플릿으로 전달
# 에러 메세지와 함께 질문 항목 폼을 다시 보여줘서 재입력할 수 있도록 함
return render(request, 'voting/detail.html', {
'question': question,
'error_message': "You didn't select a choice",
})
else:
selected_choice.votes += 1
# 변경 사항 Choice 테이블 저장
selected_choice.save()
# POST 데이터를 정상적으로 처리했으면
# 항상 HttpResponseRedirect를 반환하여 리다이렉션 처리
# 최종적으로 vote() 뷰 함수는 리다이렉트할 타겟 URL을 담은
# HttpResponseRedirect 객체 반환
return HttpResponseRedirect(reverse('voting:results', args=(question.id,)))
Templateコード
継承機能の追加
base.htmlがコードされているので、base投票を継承します.htmlテンプレートファイルを作成し、既存のテンプレートファイルごとにbase投票を行います.htmlテンプレートを継承できます.
base_voting.html
{% extends 'base.html' %}
<title>{% block title %}Voting Application Site{% endblock %}</title>
{% block sidebar %}
{{ block.super }}
<ul>
<li><a href="/voting/">Voting_Home</a></li>
</ul>
{% endblock%}
voting/index.htmlの変更{% extends "base_books.html" %}
{% block content %}
<h2>Voting Question List</h2>
...
{% endblock content %}
voting/detail.htmlの変更{% extends "base_voting.html" %}
{% block content %}
<h1>{{ question.question_text }}</h1>
...
{% endblock content%}
voting/results.htmlの変更{% extends "base_voting.html" %}
{% block content %}
...
{% endblock content%}
ログの追加
settings.pyファイルにログを設定してログを取得し、ログが必要な場所でrogerメソッドを呼び出すとよい.
記録設定で学習したコードに従って適用すればよい.
settings.pyファイルの変更
...
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
# [로그 메시지를 기록한 시간], 로그 레벨 이름
# [로거이름:라인번호], 로그 메시지 순서로 출력
'verbose': {
'format': "[%(asctime)s %(levelname)s [%(name)s:%(lineno)s] %(message)s",
'datefmt': "%d%b%Y %H:%M:%S"
}
},
'handlers': {
# DEBUG 이상의 메시지를 파일로 출력해주는 FileHandler 사용
# 로그가 기록되는 파일 이름은 D:web_programing\web_programing\logs\testsite.log
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filters': os.path.join(BASE_DIR, 'logs', 'testsite.log'),
# 위에서 정의한 verbose 포맷터 사용
'formatter': 'verbose'
},
},
'loggers': {
# testsite 로거 이름 대신에 voting 로거 이름으로 바꿨다.
# views.py 파일에서 __name__변수로 로거를 취득하기 위함이다.
'voting': {
'handlers': ['file'],
'level': 'DEBUG',
},
}
}
voting/views.変更# logging 추가
import logging
# getLogger(__name__) 메소드를 호출해서 voting.views 로거 객체 취득
logger = logging.getLogger(__name__)
...
def vote(request, question_id):
# 로거 객체의 debug 메소드를 호출해서 로거에게
# DEBUG 수준으로 로그 레코드를 생성하도록 요청
# 로거는 앞에서 수정한 settings.py 파일의 로깅 설정에 따라
# file 핸들러를 사용하여 로그 메시지를 기록한다.
logger.debug("vote().question_id: %s" % question_id)
...
logsディレクトリがない場合は、それを作成する必要があります.出典:Djangoで学ぶPythonネットワークプログラミング(ベース)-金錫勲
Reference
この問題について(投票アプリケーション-クラスビューに変更), 我々は、より多くの情報をここで見つけました https://velog.io/@jusung-c/voting-애플리케이션-클래스-뷰로-변경テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol