반응형
Notice
Recent Posts
«   2024/12   »
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 31
Today
Total
관리 메뉴

오식랜드

[python] Django Database 사용 본문

dev-log/python

[python] Django Database 사용

개발하는 오식이 2023. 1. 30. 22:37
반응형

templete과 view, url을 연결하는 방법을 알면, 링크에 따라 html을 보여줄 수 있다.

view 추가하기

polls/views.py에 뷰를 추가해 봅시다.

이 뷰들은 인수를 받기 때문에 조금 모양이 다릅니다

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def index(request):
    return HttpResponse('Hello, world!')

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

명심할 점 !

view에서는 request라는 인자를 받고, HttpResponse 함수를 반환합니다.

url 연결하기

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'),
]
  • path(패턴, 호출함수, 템플릿) : 패턴에 맞을 시 함수를 호출하게 된다.
  • question_id는 views에서 사용하는 question_id와 일치하게된다

views 에 database 파싱

views.py 파일에서 index함수를 수정해주자

from .models import Question

def index(request):
		# Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]

    # 5개 데이터를 콤마 (,)로 연결해서 하나의 문자열로 변경
    output = ', '.join([q.question_text for q in latest_question_list])

    return HttpResponse(output)

현재는 질문이 한개밖에 없어서 하나만 출력이 되어있다

templates생성

templates폴더를 생성해주자

앱 내에 생성한 후 templates폴더 내에는 앱 이름과 같이 폴더를 하나 더 만들어서 사용해주자

mysite > polls > templates> polls > index.html

이렇게 만드는 이유는

django에서 폴더명 없이 templates> index.html로 작성하게 되면

앱이 여러개가 됐을 때 다른 앱들과 구분을 못하게 되기 때문이다

index.html에는 아래 코드를 넣는다.

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

views.py의 index 함수를 수정해준다

def index(request):
    # Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    # template호출
    template = loader.get_template('polls/index.html')
    # context를 통해 데이터 전달
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))

그리고 다시 /polls/에 진입해보면 화면 구성이 바뀌어있는게 보이고, F12를 눌러 개발자도구로 확인해보면 a태그에 question id값이 잘 들어가있음을 확인할 수 있다

render()

템플릿에 context 를 채워넣어 표현한 결과를 HttpResponse 객체와 함께 돌려주는 구문이다.

views.py의 idnex함수를 render로 수정해보자

from django.shortcuts import render

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)

404 Error

현재 페이지에서 list를 클릭하면 detail페이지로 진입한다

주소창을 보면 http://127.0.0.1:8000/polls/1/ 와 같이 question id가 경로로 쓰이는데,

이 때 id값이 없는 detail페이지에 진입했을 때를 대비해 미리 에러처리를 해주자

views.py에서 detail함수 수정

from django.shortcuts import get_object_or_404, render

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

이렇게 해주면 404페이지에서 에러의 이유를 포함하여 보여준다

그리고 이제 질문에 따른 선택지를 보여주는 detail페이지를 만들어보자

templates/polls/deatil.html 생성 후 내용 입력

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

question.choice_set.all ?

Question말고 만들었었던 Choice 모델이 있다.

그 모델 안에서 선택한 질문의 key를 갖는 데이터베이스를 불러오라는 의미이다

 

지금은 데이터가 없으니 admin페이지에 가서 생성해주자

admin.py에 Choice 모델 추가

from django.contrib import admin
from .models import Question, Choice
# Register your models here.

admin.site.register(Question)
admin.site.register(Choice)

admin페이지에서 추가

detail에서 확인

 

선택지가 잘 들어가진걸 확인할 수 있다!

하드코딩된 URL 변경하기

polls/index.html 을 보면 a태그에 링크가 하드코딩 되어있다.

~
 <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
~

하지만 혹시나 urls.py에서 접근할 링크 이름을 바꾼다면 이렇게 하드코딩 되어있는 template마다 찾아서 바꿔줘야하는 번거로움이 생긴다.

하지만 우리는 name을 이용해서 변동되는 url을 자동으로 따라갈 수 있다.

name은 우리가 urls.py에서 설정해줬따.

그냥 가져다 쓰는 것 보다 여러 앱이 있을 시 겹치지 않도록 app_name을 붙여준 후 사용하자

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

이를 참조하여 template의 a태그를 수정해주자

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

View와 Templete

templete과 view, url을 연결하는 방법을 알면, 링크에 따라 html을 보여줄 수 있다.

view 추가하기

polls/views.py에 뷰를 추가해 봅시다.

이 뷰들은 인수를 받기 때문에 조금 모양이 다릅니다

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def index(request):
    return HttpResponse('Hello, world!')

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

명심할 점 !

view에서는 request라는 인자를 받고, HttpResponse 함수를 반환합니다.

url 연결하기

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'),
]
  • path(패턴, 호출함수, 템플릿) : 패턴에 맞을 시 함수를 호출하게 된다.
  • question_id는 views에서 사용하는 question_id와 일치하게된다

views 에 database 파싱

views.py 파일에서 index함수를 수정해주자

from .models import Question

def index(request):
		# Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]

    # 5개 데이터를 콤마 (,)로 연결해서 하나의 문자열로 변경
    output = ', '.join([q.question_text for q in latest_question_list])

    return HttpResponse(output)

현재는 질문이 한개밖에 없어서 하나만 출력이 되어있다

templates생성

templates폴더를 생성해주자

앱 내에 생성한 후 templates폴더 내에는 앱 이름과 같이 폴더를 하나 더 만들어서 사용해주자

mysite > polls > templates> polls > index.html

이렇게 만드는 이유는

django에서 폴더명 없이 templates> index.html로 작성하게 되면

앱이 여러개가 됐을 때 다른 앱들과 구분을 못하게 되기 때문이다

index.html에는 아래 코드를 넣는다.

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

views.py의 index 함수를 수정해준다

def index(request):
    # Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    # template호출
    template = loader.get_template('polls/index.html')
    # context를 통해 데이터 전달
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))

그리고 다시 /polls/에 진입해보면 화면 구성이 바뀌어있는게 보이고, F12를 눌러 개발자도구로 확인해보면 a태그에 question id값이 잘 들어가있음을 확인할 수 있다

render()

템플릿에 context 를 채워넣어 표현한 결과를 HttpResponse 객체와 함께 돌려주는 구문이다.

views.py의 idnex함수를 render로 수정해보자

from django.shortcuts import render

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)

404 Error

현재 페이지에서 list를 클릭하면 detail페이지로 진입한다

주소창을 보면 http://127.0.0.1:8000/polls/1/ 와 같이 question id가 경로로 쓰이는데,

이 때 id값이 없는 detail페이지에 진입했을 때를 대비해 미리 에러처리를 해주자

views.py에서 detail함수 수정

from django.shortcuts import get_object_or_404, render

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

이렇게 해주면 404페이지에서 에러의 이유를 포함하여 보여준다

그리고 이제 질문에 따른 선택지를 보여주는 detail페이지를 만들어보자

templates/polls/deatil.html 생성 후 내용 입력

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

question.choice_set.all ?

Question말고 만들었었던 Choice 모델이 있다.

그 모델 안에서 선택한 질문의 key를 갖는 데이터베이스를 불러오라는 의미이다

지금은 데이터가 없으니 admin페이지에 가서 생성해주자

admin.py에 Choice 모델 추가

from django.contrib import admin
from .models import Question, Choice
# Register your models here.

admin.site.register(Question)
admin.site.register(Choice)

admin페이지에서 추가

detail에서 확인

선택지가 잘 들어가진걸 확인할 수 있다!

하드코딩된 URL 변경하기

polls/index.html 을 보면 a태그에 링크가 하드코딩 되어있다.

~
 <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
~

하지만 혹시나 urls.py에서 접근할 링크 이름을 바꾼다면 이렇게 하드코딩 되어있는 template마다 찾아서 바꿔줘야하는 번거로움이 생긴다.

하지만 우리는 name을 이용해서 변동되는 url을 자동으로 따라갈 수 있다.

name은 우리가 urls.py에서 설정해줬따.

그냥 가져다 쓰는 것 보다 여러 앱이 있을 시 겹치지 않도록 app_name을 붙여준 후 사용하자

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

이를 참조하여 template의 a태그를 수정해주자

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

templete과 view, url을 연결하는 방법을 알면, 링크에 따라 html을 보여줄 수 있다.

view 추가하기

polls/views.py에 뷰를 추가해 봅시다.

이 뷰들은 인수를 받기 때문에 조금 모양이 다릅니다

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def index(request):
    return HttpResponse('Hello, world!')

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

명심할 점 !

view에서는 request라는 인자를 받고, HttpResponse 함수를 반환합니다.

url 연결하기

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'),
]
  • path(패턴, 호출함수, 템플릿) : 패턴에 맞을 시 함수를 호출하게 된다.
  • question_id는 views에서 사용하는 question_id와 일치하게된다

views 에 database 파싱

views.py 파일에서 index함수를 수정해주자

from .models import Question

def index(request):
		# Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]

    # 5개 데이터를 콤마 (,)로 연결해서 하나의 문자열로 변경
    output = ', '.join([q.question_text for q in latest_question_list])

    return HttpResponse(output)

현재는 질문이 한개밖에 없어서 하나만 출력이 되어있다

templates생성

templates폴더를 생성해주자

앱 내에 생성한 후 templates폴더 내에는 앱 이름과 같이 폴더를 하나 더 만들어서 사용해주자

mysite > polls > templates> polls > index.html

이렇게 만드는 이유는

django에서 폴더명 없이 templates> index.html로 작성하게 되면

앱이 여러개가 됐을 때 다른 앱들과 구분을 못하게 되기 때문이다

index.html에는 아래 코드를 넣는다.

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

views.py의 index 함수를 수정해준다

def index(request):
    # Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    # template호출
    template = loader.get_template('polls/index.html')
    # context를 통해 데이터 전달
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))

그리고 다시 /polls/에 진입해보면 화면 구성이 바뀌어있는게 보이고, F12를 눌러 개발자도구로 확인해보면 a태그에 question id값이 잘 들어가있음을 확인할 수 있다

render()

템플릿에 context 를 채워넣어 표현한 결과를 HttpResponse 객체와 함께 돌려주는 구문이다.

views.py의 idnex함수를 render로 수정해보자

from django.shortcuts import render

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)

404 Error

현재 페이지에서 list를 클릭하면 detail페이지로 진입한다

주소창을 보면 http://127.0.0.1:8000/polls/1/ 와 같이 question id가 경로로 쓰이는데,

이 때 id값이 없는 detail페이지에 진입했을 때를 대비해 미리 에러처리를 해주자

views.py에서 detail함수 수정

from django.shortcuts import get_object_or_404, render

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

이렇게 해주면 404페이지에서 에러의 이유를 포함하여 보여준다

그리고 이제 질문에 따른 선택지를 보여주는 detail페이지를 만들어보자

templates/polls/deatil.html 생성 후 내용 입력

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

question.choice_set.all ?

Question말고 만들었었던 Choice 모델이 있다.

그 모델 안에서 선택한 질문의 key를 갖는 데이터베이스를 불러오라는 의미이다

지금은 데이터가 없으니 admin페이지에 가서 생성해주자

admin.py에 Choice 모델 추가

from django.contrib import admin
from .models import Question, Choice
# Register your models here.

admin.site.register(Question)
admin.site.register(Choice)

admin페이지에서 추가

detail에서 확인

선택지가 잘 들어가진걸 확인할 수 있다!

하드코딩된 URL 변경하기

polls/index.html 을 보면 a태그에 링크가 하드코딩 되어있다.

~
 <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
~

하지만 혹시나 urls.py에서 접근할 링크 이름을 바꾼다면 이렇게 하드코딩 되어있는 template마다 찾아서 바꿔줘야하는 번거로움이 생긴다.

하지만 우리는 name을 이용해서 변동되는 url을 자동으로 따라갈 수 있다.

name은 우리가 urls.py에서 설정해줬따.

그냥 가져다 쓰는 것 보다 여러 앱이 있을 시 겹치지 않도록 app_name을 붙여준 후 사용하자

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

이를 참조하여 template의 a태그를 수정해주자

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

 

templete을 통해 html코드를 넣을 수 있고,

templete과 view, url을 연결하는 방법을 알면, 링크에 따라 html을 보여줄 수 있다.

view 추가하기

polls/views.py에 뷰를 추가해 봅시다.

이 뷰들은 인수를 받기 때문에 조금 모양이 다릅니다

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def index(request):
    return HttpResponse('Hello, world!')

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

명심할 점 !

view에서는 request라는 인자를 받고, HttpResponse 함수를 반환합니다.

url 연결하기

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'),
]
  • path(패턴, 호출함수, 템플릿) : 패턴에 맞을 시 함수를 호출하게 된다.
  • question_id는 views에서 사용하는 question_id와 일치하게된다

views 에 database 파싱

views.py 파일에서 index함수를 수정해주자

from .models import Question

def index(request):
		# Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]

    # 5개 데이터를 콤마 (,)로 연결해서 하나의 문자열로 변경
    output = ', '.join([q.question_text for q in latest_question_list])

    return HttpResponse(output)

현재는 질문이 한개밖에 없어서 하나만 출력이 되어있다

templates생성

templates폴더를 생성해주자

앱 내에 생성한 후 templates폴더 내에는 앱 이름과 같이 폴더를 하나 더 만들어서 사용해주자

mysite > polls > templates> polls > index.html

이렇게 만드는 이유는

django에서 폴더명 없이 templates> index.html로 작성하게 되면

앱이 여러개가 됐을 때 다른 앱들과 구분을 못하게 되기 때문이다

index.html에는 아래 코드를 넣는다.

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

views.py의 index 함수를 수정해준다

def index(request):
    # Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    # template호출
    template = loader.get_template('polls/index.html')
    # context를 통해 데이터 전달
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))

그리고 다시 /polls/에 진입해보면 화면 구성이 바뀌어있는게 보이고, F12를 눌러 개발자도구로 확인해보면 a태그에 question id값이 잘 들어가있음을 확인할 수 있다

render()

템플릿에 context 를 채워넣어 표현한 결과를 HttpResponse 객체와 함께 돌려주는 구문이다.

views.py의 idnex함수를 render로 수정해보자

from django.shortcuts import render

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)

404 Error

현재 페이지에서 list를 클릭하면 detail페이지로 진입한다

주소창을 보면 http://127.0.0.1:8000/polls/1/ 와 같이 question id가 경로로 쓰이는데,

이 때 id값이 없는 detail페이지에 진입했을 때를 대비해 미리 에러처리를 해주자

views.py에서 detail함수 수정

from django.shortcuts import get_object_or_404, render

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

이렇게 해주면 404페이지에서 에러의 이유를 포함하여 보여준다

그리고 이제 질문에 따른 선택지를 보여주는 detail페이지를 만들어보자

templates/polls/deatil.html 생성 후 내용 입력

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

question.choice_set.all ?

Question말고 만들었었던 Choice 모델이 있다.

그 모델 안에서 선택한 질문의 key를 갖는 데이터베이스를 불러오라는 의미이다

지금은 데이터가 없으니 admin페이지에 가서 생성해주자

admin.py에 Choice 모델 추가

from django.contrib import admin
from .models import Question, Choice
# Register your models here.

admin.site.register(Question)
admin.site.register(Choice)

admin페이지에서 추가

detail에서 확인

선택지가 잘 들어가진걸 확인할 수 있다!

하드코딩된 URL 변경하기

polls/index.html 을 보면 a태그에 링크가 하드코딩 되어있다.

~
 <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
~

하지만 혹시나 urls.py에서 접근할 링크 이름을 바꾼다면 이렇게 하드코딩 되어있는 template마다 찾아서 바꿔줘야하는 번거로움이 생긴다.

하지만 우리는 name을 이용해서 변동되는 url을 자동으로 따라갈 수 있다.

name은 우리가 urls.py에서 설정해줬따.

그냥 가져다 쓰는 것 보다 여러 앱이 있을 시 겹치지 않도록 app_name을 붙여준 후 사용하자

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

이를 참조하여 template의 a태그를 수정해주자

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

templete과 view, url을 연결하는 방법을 알면, 링크에 따라 html을 보여줄 수 있다.

view 추가하기

polls/views.py에 뷰를 추가해 봅시다.

이 뷰들은 인수를 받기 때문에 조금 모양이 다릅니다

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def index(request):
    return HttpResponse('Hello, world!')

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

명심할 점 !

view에서는 request라는 인자를 받고, HttpResponse 함수를 반환합니다.

url 연결하기

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'),
]
  • path(패턴, 호출함수, 템플릿) : 패턴에 맞을 시 함수를 호출하게 된다.
  • question_id는 views에서 사용하는 question_id와 일치하게된다

views 에 database 파싱

views.py 파일에서 index함수를 수정해주자

from .models import Question

def index(request):
		# Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]

    # 5개 데이터를 콤마 (,)로 연결해서 하나의 문자열로 변경
    output = ', '.join([q.question_text for q in latest_question_list])

    return HttpResponse(output)

현재는 질문이 한개밖에 없어서 하나만 출력이 되어있다

templates생성

templates폴더를 생성해주자

앱 내에 생성한 후 templates폴더 내에는 앱 이름과 같이 폴더를 하나 더 만들어서 사용해주자

mysite > polls > templates> polls > index.html

이렇게 만드는 이유는

django에서 폴더명 없이 templates> index.html로 작성하게 되면

앱이 여러개가 됐을 때 다른 앱들과 구분을 못하게 되기 때문이다

index.html에는 아래 코드를 넣는다.

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

views.py의 index 함수를 수정해준다

def index(request):
    # Question 데이터 중 5개만 호출
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    # template호출
    template = loader.get_template('polls/index.html')
    # context를 통해 데이터 전달
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))

그리고 다시 /polls/에 진입해보면 화면 구성이 바뀌어있는게 보이고, F12를 눌러 개발자도구로 확인해보면 a태그에 question id값이 잘 들어가있음을 확인할 수 있다

render()

템플릿에 context 를 채워넣어 표현한 결과를 HttpResponse 객체와 함께 돌려주는 구문이다.

views.py의 idnex함수를 render로 수정해보자

from django.shortcuts import render

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)

404 Error

현재 페이지에서 list를 클릭하면 detail페이지로 진입한다

주소창을 보면 http://127.0.0.1:8000/polls/1/ 와 같이 question id가 경로로 쓰이는데,

이 때 id값이 없는 detail페이지에 진입했을 때를 대비해 미리 에러처리를 해주자

views.py에서 detail함수 수정

from django.shortcuts import get_object_or_404, render

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

이렇게 해주면 404페이지에서 에러의 이유를 포함하여 보여준다

그리고 이제 질문에 따른 선택지를 보여주는 detail페이지를 만들어보자

templates/polls/deatil.html 생성 후 내용 입력

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

question.choice_set.all ?

Question말고 만들었었던 Choice 모델이 있다.

그 모델 안에서 선택한 질문의 key를 갖는 데이터베이스를 불러오라는 의미이다

지금은 데이터가 없으니 admin페이지에 가서 생성해주자

admin.py에 Choice 모델 추가

from django.contrib import admin
from .models import Question, Choice
# Register your models here.

admin.site.register(Question)
admin.site.register(Choice)

admin페이지에서 추가

detail에서 확인

선택지가 잘 들어가진걸 확인할 수 있다!

하드코딩된 URL 변경하기

polls/index.html 을 보면 a태그에 링크가 하드코딩 되어있다.

~
 <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
~

하지만 혹시나 urls.py에서 접근할 링크 이름을 바꾼다면 이렇게 하드코딩 되어있는 template마다 찾아서 바꿔줘야하는 번거로움이 생긴다.

하지만 우리는 name을 이용해서 변동되는 url을 자동으로 따라갈 수 있다.

name은 우리가 urls.py에서 설정해줬따.

그냥 가져다 쓰는 것 보다 여러 앱이 있을 시 겹치지 않도록 app_name을 붙여준 후 사용하자

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

이를 참조하여 template의 a태그를 수정해주자

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
반응형

'dev-log > python' 카테고리의 다른 글

[python] Django Generic View 사용하기  (0) 2023.01.30
[python] Django Form 생성  (0) 2023.01.30
[python] Django Admin Page  (0) 2023.01.30
[python] Django API 사용하기  (0) 2023.01.30
[python] Django Database 사용  (0) 2023.01.30
Comments