간단한 설문조사 웹사이트를 예제로 개발해보려한다.
우선 필요한 화면은
설문조사 사이트 홈화면(설문조사 종류 제시)과 index.html
설문조사 투표 화면의 detail.html
설문 결과를 보여주는 result.html 3가지 template으로 설계할것이다.
보통 view와 template은 1:1또는 N:1로 짠다.
해당 예제의 경우 투표하는 과정에서 Redirection과 같은 로직이 필요하므로,
view에만 vote메서드를 추가할것이다. (나머지는 template과 매칭되게 메서드 작성)
이때 DB 테이블은 Question과 Choice로 크게 나눠서 데이터를 저장할것이다.
urlpatterns = [path('admin/', admin.site.urls), path('polls/', views.index, name='index'), path('polls/<int:question_id>/', views.detail, name = 'detail'), path('polls/<int:question_id>/results/', views.results, name = 'results'), path('polls/<int:question_id>/vote/', views.vote, name='vote'),]
URL 저장겸, URL 매핑시 매칭되는 메서드가 실행된다.
위와 같은 방식으로 Url을 정리할수 있지만, 아래와 같은 방식이 더좋을것이다.
urlpatterns = [
path('admin/', admin.site.urls),
path('polls/', include('polls.urls')),
]
app_name = 'polls'
urlpatterns =[
path('', views.index, name='index'),
path('<int:question_id>/',views.detail, name='detail'),
path('<int:question_id>/results/', views.results, name='results'),
path('<int:question_id>/vote/', views.vote , name='vote'),
]세요
그 이유는 모듈을 계층적으로 짜는것이 나중에 변경도 쉬워지고 확장성에도 매우 유리하기 때문이다. 우리가 유사한 파일끼리 폴더에 저장하는것과 같다
def index(request):
latest_question_list = Question.objects.all().order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request,'polls/index.html', context)
첫 화면을 렌더링해주는 index메서드는 import한 Question을 통해 모든 리스트를 넘겨준다
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
detail은 사용자가 선택한 questionId를 받아 다시 html에 넘겨준다
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
HttpResponseRedirect를 리턴합니다.
HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
여기서 Redirect가 이용됐는데, 보통 Post방식의 폼을 처리할때 그 결과를 보여줄수있는 페이지로 이동시
HttpResponseRedirect 객체를 리턴하는 방식을 이용한다.
또한 reverse() 함수가 이용됐는데,
보통 http요청시 url이 들어오면 url 스트링을 urls.py에서 찾아 메서드를 찾아가는 방식이라면, 해당 코드처럼 polls:result와 같이 패턴명으로 역으로 url을 얻어내는 방식이다.
def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})
admin에서 로그인과, question , choice 을 만들고
첫 index화면
detail 화면. 여기서 vote 누르는 순간 vote로 넘어간다.
result 로 마무리
ㅡㅡㅡㅡㅡ
초반에 터미널로 작업하다가 오타 몇개 치고 안되는순간 시간 너무 잡아먹어서 결국 파이참 깔아서 했다. 터미널에 익숙해져야 한다고 하는데 .. 이렇게 하는게 맞나?싶다