Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- id # tr # 환경변수
- Virtual Box 7.0.6
- Ubuntu 20.04
- 부스트캠프
- 보기 편하라고 만든
- 후기
- 운영체제론
- 네이버 부스트 코스
- 백준 #baekjoon # 2563
- 웹/모바일
- 네이버
- 8기
Archives
- Today
- Total
Miner
DAY 12 본문
10/31 파이썬 장고 프레임워크를 사용해서 API 서버 만들기(2)
1. 뷰(Views) 와 템플릿(Templates)
- poll/views.py
from .models import *
from django.shortcuts import render
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'first_question': latest_question_list[0]}
return render(request, 'polls/index.html', context)
- templates/poll/index.html
<ul>
<li>{{first question}}</li>
<ul>
2. 템플릿에서 제어문 사용하기
- templates/poll/index.html
{% if questions %}
<ul>
{% for question in questions %}
<li>{{question}}</li>
{% endfor %}
</ul>
{% else %}
<p>no questions</p>
{% endif %}
- views.py
from .models import *
from django.shortcuts import render
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'questions': latest_question_list}
#context = {'questions': []}
return render(request, 'polls/index.html', context)
3. 상세 페이지 만들기
- poll/views.py
...
def detail(request, question_id):
question = Question.objects.get(pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
- poll/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('some_url', views.some_url),
path('<int:question_id>/', views.detail, name='detail'),
]
- templates/poll/detail.html
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
4. 상세 페이지로 링크 추가하기
- poll/urls.py
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.index, name='index'),
path('some_url', views.some_url),
path('<int:question_id>/', views.detail, name='detail'),
]
- templates/poll/index.html
{% if questions %}
<ul>
{% for question in questions %}
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
<ul>
{% else %}
<p>no questions</p>
{% endif %}
5. 404 에러 처리하기
- poll/views.py
from models.py import *
from django.http import HttpResponse
from django.http import Http404
from django.shortcuts import render , get_object_or_404
...
def detail(request, question_id):
"""
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
"""
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
6. 폼(forms)
- poll/views.py
...
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': '선택이 없습니다.'})
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:index'))
- poll/urls.py
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.index, name='index'),
path('<int:question_id>/', views.detail, name='detail'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
- poll/detail.html
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
<h1>{{ question.question_text }}</h1>
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
{% 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>
7. 에러 방어하기 1,2
- polls/views.py
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': f"선택이 없습니다. id={request.POST['choice']}"})
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
동시에 vote 하는 경우, 서버가 아니라 DB로 연결
- polls/views.py
from django.urls import reverse
from django.db.models import F
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': f"선택이 없습니다. id={request.POST['choice']}"})
else:
# A서버에서도 Votes = 1
# B서버에서도 Votes = 1
selected_choice.votes = F('votes') + 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:index'))
8. result 조회 페이지
- polls/views.py
from django.shortcuts import get_object_or_404, render
...
def vote(request, question_id):
...
else:
selected_choice.votes = F('votes') + 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:result', args=(question.id,)))
def result(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/result.html', {'question': question})
- polls/result.html
<h1>{{ question.question_text }}</h1><br>
{% for choice in question.choice_set.all %}
<label>
{{ choice.choice_text }} -- {{ choice.votes }}
</label>
<br>
{% endfor %}
- polls/urls.py
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.index, name='index'),
path('<int:question_id>/', views.detail, name='detail'),
path('<int:question_id>/vote/', views.vote, name='vote'),
path('<int:question_id>/result/', views.result, name='result'),
]
※ args 활용
※ kwargs 활용