from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('<int:question_id>/', views.detail, name='detail'),
# ex: /polls/5/results/
path('<int:question_id>/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
메인 Project의 urls.py에서 polls/ 디렉토리로 분기해주면, polls/urls.py에서는 app 내부의 logic을 담당하는 함수들로 분기해준다.
질문의 번호를 담당하는 index, 내용을 담당하는 detail, 결과를 담당하는 results, 선택 결과를 알려주는 vote 함수로 나뉜다.
질문의 번호를 인자로 넘겨주기 위해서 int:question_id라고 넘겨주는데, question_id는 각 함수에, argument로 넘어간다.
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
question_text = models.CharField(max_lenght=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
튜토리얼의 설문조사 앱은 Question과 Choice로 이루어져있고, Question은 text, 날짜를 Field로 갖고 있다.
Choice는 질문과 선택지, 각 선택지들의 선택 횟수를 Field로 갖고 있다.
django.db 패키지에서 models 모듈을 임포트하면, DB에 저장하기 위한 charField(문자), DateTimeField(시간), IntegerField(정수) Field 형식을 갖고 있다.
이렇게 models.py에 저장한 내용은 migration을 거쳐
DB에 저장된다.
models.py를 작성한 후 mysite의 DB에 아래와 같이 migrate 시키면
python manage.py sqlmigrate polls 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" (
"id" serial NOT NULL PRIMARY KEY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL,
"question_id" integer NOT NULL
);
ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_c5b4b260_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
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):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
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):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
Views.py는 Polls App의 주요 로직을 담당한다.
index 함수는 request로부터 받은 Question_list를 생성날짜 순으로 ordering하여 latest_question_list에 넣은 다음 render()함수를 통해 웹페이지에 출력한다.
물론 그냥 출력하는 것이 아니라, template을 통해 출력한다.
polls/index.html을 통해 rendering해주는데, render()함수를 사용한다.
render함수는 latest_question_list를 Dictionary로 담아 argument로 보낸다. index.html을 Template으로 삼아, context를 웹페이지에 출력하게 만든다.
detail함수는 polls/5와 같이 특정 숫자를 인자로 함께 받으면, 해당 id의 question을 출력한다. Question의 객체를 get하는 함수인 Question.objects.get함수에 question_id를 argument로 넣어 question에 저장한다. 이 때 만약 그런 question이 존재하지 않으면, exception 예외처리를 통해 Question does not exist와 함께 404 error를 출력한다.
존재한다면, polls/detail.html이라는 Template을 통해 질문을 출력한다.
results함수는 Question의 결과를 출력하는데, results.html이라는 Template을 통해 출력한다.
vote 함수는 설문조사 결과를 출력하는데, question_id를 통해 DB에서 질문을 받아, 그 질문과 함께 등록된 선택지들을 selected_choice에 저장한다.
Exception을 통해 KeyError가 나면, 다시 detail.html로 돌아가게 만든다.
그렇지 않으면, selected_choice함수의 votes 필드를 1 증가시켜서 투표수를 증가시킨후 save함수를 통해 저장한다.
template이란 View를 통해 거친 내부 Logic의 결과값들을 사용자 친화적으로 웹페이지에 출력하는 것이다. CSS 효과를 넣은 HTML과 Javascript를 통해 Frontend를 구현한 것이 Template이다.
위 코드에서 views.py에서 구현한 내부 logic을 render함수를 통해 index.html/detail.html 등으로 넘겨주면, index.html과 detail.html에서 그 인자를 넘겨받아 개발자 편리대로 출력한다.
여기서는 Django Tutorial의 내부 Logic을 설명하는 것이 더 중요하기 때문에 html 문서의 설명에 대해서는 생략한다.
https://docs.djangoproject.com/ko/3.0/intro/tutorial03/
이 곳 Django Tutorial에 html 코드가 있음.

Django는 사용자가 DB관리, 인증, 여러 프레임워크 관리 등을 하는데 있어 편리한 기능을 제공하기 위해 Admin 사이트를 제공한다.\
python manage.py createsuperuser를 통해 아이디와 pw를 만들고, https://localhosts:포트번호/admin 사이트에 접속할 수 있다.
사용자가 서버에 접근하면, 메인 사이트의 urls.py를 통해 각 App으로 분기하고, 각 App에서 각자 logic을 처리할 함수로 분기한다.
Django는 MVT 패턴을 기반으로 웹 어플리케이션 개발 프레임워크를 제공하는데, Models를 통해서 DB와 상호작용하며 관리하고, Views를 통해 Data를 가공하여, Front-end에 출력할 내부 Logic을 짜고, Template을 통해 Front-end를 출력한다.