Django Polls예제

김용녀·2022년 7월 12일
0

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

우선 필요한 화면은

설문조사 사이트 홈화면(설문조사 종류 제시)과 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개의 댓글