Django Polls예제

김용녀·2022년 7월 12일

간단한 설문조사 웹사이트를 예제로 개발해보려한다.

우선 필요한 화면은

설문조사 사이트 홈화면(설문조사 종류 제시)과 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'),
]세요

그 이유는 모듈을 계층적으로 짜는것이 나중에 변경도 쉬워지고 확장성에도 매우 유리하기 때문이다. 우리가 유사한 파일끼리 폴더에 저장하는것과 같다

View 메서드만 가져왔다


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 로 마무리

ㅡㅡㅡㅡㅡ
초반에 터미널로 작업하다가 오타 몇개 치고 안되는순간 시간 너무 잡아먹어서 결국 파이참 깔아서 했다. 터미널에 익숙해져야 한다고 하는데 .. 이렇게 하는게 맞나?싶다

profile
어서오세요

0개의 댓글