Django2.1 내가 보는 강의 tutorial 4

Frameworks/Django|2019.03.15 07:00

Django2.1 내가 보는 강의 tutorial 4

기본적인 프레임은 갖춰졌다. 
이제 데이터를 관리할 관리자 페이지를 만들어야 한다.
또한 현재는 설문조사의 제목만 리스트로 나열하는 페이지 밖에 없는데
설문조사의 내용을 볼수 있는 detail 페이지와 투표기능, 
설문조사에 참여하고 결과를 볼 수 있는 result 페이지를 만들 것이다. 

admin 페이지 만들기

데이터를 관리해주는 어드민 페이지는 기본적으로 Django가 제공해 준다.
처음 Django 프로젝트를 생성했을 때 이미 기본적으로 어드민페이지가 연결되어 있다. 
config/urls.py 파일을 보면 아래와 같이 127.0.0.1:8000/admin/ 이라는 URL이 연결되어 있다.

urlpatterns = [
path('admin/', admin.site.urls),
]
127.0.0.1:8000/admin/ 로 접속해보면 다음과 같이 어드민 페이지로 접근할 수 있다.
처음에 createsuperuser 명령으로 만들었던 관리자 계정으로 접속해 본다.


기본적으로 사용자의 계정을 관리할 수 있는 테이블만 존재한다. 

여기에서 polls앱에서 다룰 모델들을 등록해줘야 사용할 수 있다.



polls앱의 데이터를 관리해줄 어드민 페이지를 만든다기 보다 등록해주는 개념이다.
polls/admin.py 에 다음 내용을 추가 해준다.
앱에서 관리할 데이터 모델을 추가해주면 된다.

from django.contrib import admin
from .models import Choice, Question

admin.site.register(Question)
admin.site.register(Choice)
다시 확인해보면 Polls라는 앱에서 사용할 Question과 Choice라는 테이블이 생성된 것을 볼 수 있다. 


일단 Questions로 들어가서 질문지를 등록해 본다.

Questions를 누르고 들어가보면 오른쪽 위쪽에 QUESTION 추가라는 버튼이 있다. 



polls/models.py 에서 Question 모델에 선언했던 question_text 항목을 볼 수 있다. 

pub_date는 등록되는 시간을 자동으로 채워주기 때문에 입력란이 보이지 않는다.



저장 버튼을 누르면 잘 저장되는 것을 확인 할 수 있다.



마찬가지로 Choice 항목을 추가 해본다.

Choice 모델에서 Question 항목을 외래키로 사용하겠다고 선언했다.

어떤 질문에 대한 선택지냐를 연결시켜주기 때문에 Question에 등록된 항목을 드롭다운형식으로 보여준다. 

하나를 선택하고 Choice_text를 정해주고 저장한다.




질문지를 하나 더 만들고 해당질문에 대한 선택지를 만들어준다.




이렇게 생성된 데이터는 다음과 같다.
질문 - 좋아하는 꽃은? 선택 - 장미, 백합, 튤립, 국화
질문 - 좋아하는 나무는? 선택 - 은행나무, 대나무, 소나무, 단풍나무

이제 질문리스트를 보여주고, 질문을 클릭하여 들어가면 해당 질문에 대한 선택지를 보여주는 화면과 그 화면에서 선택지를 선택하여 투표에 반영하는 페이지와 그 결과를 확인하는 페이지를 보여주는 화면이 있어야 할 것이다. 
각 화면마다 URL이 있어야 하고, 그 URL에서 보여줄 템플릿과 템플릿 안에 들어갈 내용을 지정해 줘야 한다. 
각각 화면에 대한 View와 Template, URL을 만들어 준다.

View에 detail, result, vote추가 하기

View에 detail, result 추가 하기
polls/views.py을 다음과 같이 코드를 작성한다.

from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from .models import Question, Choice

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)
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})

def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})

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()
return HttpResponseRedirect(reverse('results', args=(question.id,)))


get_object_or_404는 해당 페이지가 없을 때 나타나는 404를 지정해준다는 의미이다. 

vote()는 아직 정확히 이해하기 힘드니 일단은 코드만 보고 넘어간다.


Templates에 index.html 수정하기, detail.html, results.html 추가하기

templates/index.html

{% url 'detail' question.id %} 는 /detail/1 이런식의 문자열을 반환한다. 

<a>태그를 누르면 찾아가야할 링크를 표현한다.

{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}


templates/detail.html


<h1>{{ question.question_text }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url 'vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
<input type="submit" value="Vote">
</form>


templates/results.html


<h1>{{ question.question_text }}</h1>

<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>

<a href="{% url 'detail' question.id %}">Vote again?</a>


각 페이지로 연결시켜주기 위한 URL 설정하기

polls/urls.py 의 urlpatterns를 다음과 같이 수정한다. 

모델의 데이터는 id 를 갖는다. 그 id는 Primary Key로 고유한 값을 나타낸다. 

<int:pk>는 Question의 데이터를 pk값으로 가져와 보여주겠다는 의미이다. 

조금 전 등록했던 "좋아하는 꽃은" 이라는 Question 모델의 데이터는 id=1의 값을 가진다.

127.0.0.1:8000/polls/1 이렇게 URL을 적어주면 id값이 1인 "좋아하는 꽃"은 이라는 데이터를 가져와 보여주겠다는 의미이다.

from django.urls import path
from . import views

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'),
]

다시 서버를 실행해서 결과물을 확인한다.





댓글()