본문 바로가기
W | eb

Django Template

by 덞웖이 2024. 10. 8.

환경

- Ubuntu Server 22.04 
- VSCode Insider 
- Remote SSH Extension 
- Python 3.10 venv
- Django 5.1.1
- SQLite 3.37.2

준비

# 프로젝트, env 생성은 지난 포스팅 참고
source django_env/bin/activate
# 프로젝트 폴더를 옮겼다면 
# vi django_env/bin/activate에서 virtual_env 경로를 바꿔줘야함 😫
# vi django_env/bin/pip 의 shebang 경로 (#!)도 바꿔준다

# @test_proj/polls : 템플릿 준비
mkdir -p templates/polls && \
touch templates/polls/index.html && \
touch templates/polls/detail.html
touch templates/polls/result.html

실행

1. The Templates

<!-- 컨텍스트와 템플릿 지역 변수 안 햇갈리는게 포인트 🤡 -->
<!-- 그냥 리엑트 쓰면 안되? 😁 -->
<!-- /templates/polls/index.html -->
{% if qs %}
<ul>
    {% for q in qs %}
    <!-- <li><a href="/polls/{{ q.id }}">{{ q.question_text }}</a></li> -->
    <!-- OR use the 'name' argument from the urls.py -->
    <li><a href="{% url 'polls:detail' q.id %}">{{ q.question_text }}</a></li>
    {% endfor %}
</ul>
{% else %}
<p>No question</p>
{% endif %}

<!-- -------------------------- -->

<!-- /templates/polls/detail.html -->
{% if err %}
<p style="background-color: salmon; color:black">{{ err }}</p>
{% endif %}

<!-- 이게 double quote 없이 된다고 ? 😮 ... 난 쓸거임 -->
<form action="{% url 'polls:vote' q.id %}" method="post">
    <!-- token for the form 🥴-->
    {% csrf_token %}
    
    <h2>{{ q.question_text }}</h2>
    
    <!-- METHODS IN CONTEXT: NO PARENTHESIS -->
    {% for c in q.choice_set.all %}
    
    	<!-- increment by 1 -->
        <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ c.id }}">
        <label for="choice{{ forloop.counter }}">
            {{ c.choice_text }}
        </label>
        <br>
    {% endfor %}
    <input type="submit" value="Vote">
</form>

<!-- -------------------------- -->

<!-- /templates/polls/result.html -->
<h2>{{ q.question_text }}</h2>
<!-- METHODS IN CONTEXT: NO PARENTHESIS -->
{% for c in q.choice_set.all %}
    <label>
        {{ c.choice_text }} votes: {{ c.votes }}
    </label>
    <br>
{% endfor %}

2. views.py

# polls/views.py
from django.http import Http404, HttpResponse
from .models import *
from django.shortcuts import render, get_object_or_404
from django.db.models import F

# polls 루트
def index(request):
    qs = Question.objects.order_by('-pub_date')[:5]
    context = {'qs': qs}
    return render(request, 'polls/index.html', context)

# 질문별 상세 페이지
def detail(request, question_id):
    # try:
    #     q = Question.objects.get(pk=question_id)
    # except Question.DoesNotExist:
    #     raise Http404("404 nope")
	# OR
	question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'q': q})

# 상세 페이지 CRUD
def vote(request, question_id):
    q = get_object_or_404(Question, pk=question_id)
    try:
    	# 'choice' == the name attrib of the input tag
        ch = q.choice_set.get(pk=request.POST['choice'])
	
    # 선택 안 했을때 & 페이지가 로드 된 후 테이블이 없어진 경우 & 기타 integrity
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {'q': q, 'err': 'You must choose!'})
    else:
    	# DB에서 연산하게 함 ( += 1 ㄴㄴ)
        ch.votes = F('votes') + 1
        ch.save()
	# 인자 튜플임 !!🐱‍🐉
    return HttpResponseRedirect(reverse('polls:result', args=(question_id,)))
    
def result(request, question_id):
    q = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/result.html', {'q': q})

3. urls.py

# polls/urls.py
from django.urls import path
from . import views

# 중복된 name 방지하기 위해서 namespace specify (임의 지정 가능)
# index에서 {% url 'polls:detail' q.id %}로 수정해줘야 함
app_name = 'polls' # urls.py 안에 있는 app_name을 찾게 predefine 돼있음

urlpatterns = [
    path('', views.index, name='index'),
    # 🤢
    path('<int:question_id>', views.detail, name='detail'),
    # for vote post request
    path('<int:question_id>/vote/', views.vote, name='vote'),
    # result
    path('<int:question_id>/result', views.result, name='result'),
]

"왜 안돼지?"

 

'W | eb' 카테고리의 다른 글

Django CRUD: API  (0) 2024.10.09
Django CRUD: Serialize  (0) 2024.10.08
Django CRUD: Admin  (1) 2024.10.08
Django MVC(MTV)  (0) 2024.10.07
HTML  (0) 2024.10.02