URL
view
template
이 어떻게 연결되는 지 보자악 !
view
를 만들어 보자.먼저 이것만 기억해보자
view에서는 request라는 인수를 받고, HttpRespose를 return 한다
- "request에는 여러가지 정보들이 담겨 있을 것이고 다시 response 해줄것이다" 이게 다임
- 긍까, return전까지 여러가지 작업을 추가해놓은다음 그 값을 return 하겠다는 말이지 ㅋㅎ ^_^
view
에 새로운 기능 추가하기polls/views.py
에 세부(detail)
, 결과(result)
, 투표(vote)
기능 추가from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world.")
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id) # HttpResponse return 하지 ?
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id) # HttpResponse return 하지 ?
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id) # HttpResponse return 하지 ?
view
를 호출하기 위해 urls.py코드 재 작성polls/urls.py
에서 고고 from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'), # ex: /polls/
path('<int:question_id>/', views.detail, name='detail'), # ex: /polls/5/
path('<int:question_id>/results/', views.results, name='results'), # ex: /polls/5/results/
path('<int:question_id>/vote/', views.vote, name='vote'), # ex: /polls/5/vote/
]
새로운 기능을 가진
views.py
와urls.py
를 연결 시켰다 ! !
- 이제 뭘 해보자.. !
request
에서 question
("what's up")을 출력하도록 해보자view
에서 request
는 그 hellow, world
만 출력하도록 되어있었다.hellow, world
만 보일것 이다.question
을 출력하도록 해보장"What's up"
이 출력된다 ! !! ! from django.http import HttpResponse
from django.template import loader
from .models import Question # 이자식 추가하고 ㅡ ㅡ
# Create your views here.
def index(request):
# return HttpResponse("Hello, world.") # 전 출력 내용 요건 추가 ㄴㄴ
latest_question_list = Question.objects.order_by('-pub_date')[:5] #퀘스쳔 데이트중, 출판일자를 정렬하여 5개까지만 가지고와라
output = ', '.join([q.question_text for q in latest_question_list]) # 이 5개를 콤마로 연결해서 스트링으로(문자열)만들게되고 이걸 출력
return HttpResponse(output)
# 아래는 그대로 두자악 !
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)
rander()
쓰는거from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
output = ', '.join([q.question_text for q in latest_question_list])
return HttpResponse(output)
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)
어떻게 하면 수정 영향범위 를 줄일 수 있을 까 .. 고민해야한다 .. !?
- 클라이언트에게 보여주는걸 목적으로 그냥 막 작성한
polls/views.py
안에있는 python 코드를 그대로 가지고 프론트 앤드가 디자인을 수정하기엔 좀 마니 어려워 쏘 복잡띠,,,
- views.py안에있는 python 코드들에 디자인을 위한 코드들이 같이있다 ㅡ ㅡ
- 페이지가 보여지는 방식을 바꿀라면 ? python 코드 다바꿔야지 ;;;;
그니까,
views.py
에서 사용할 수 있는templates
을 만들어서 따로 작성해서, python 코드와 / 디자인을 위한 코드를 분리해보자
view
와 디자인 담당인 Template
분리하자views.py
안에 index 뷰
를 업데이트 하면서context
라는 새로운 변수를 넣었을 때 , polls/detail.html
이라는 템플릿을 어떻게 받아오는지 보자polls/templates/polls
안에 index.html
을 만들고 아래 내용을 넣자<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
Templates
이용하여 polls/views.py
에 index
를 업데이트 한다.Templates
을 하는데 왜때문에 views.py
를 고치냐 ? from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader # 이자식이 추가되었고
from .models import Question
# Create your views here.
def index(request):
#return HttpResponse("Hello, world")
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html') # "polls/index.html" templates를 불러와서 가장 첫줄을 받는다
context = { # 그런후 context로 전달한다. / context는 템플릿에서 쓰이는 변수명과 Python 객체를 연결하는 사전형 값이다.
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context,request))
위 코드와 동일하고 좀 짧은 지름길이 있다
- index 뷰를 단축 기능으로 작성해볼궤 !
render()
사용# polls/views.py from django.shortcuts import render ` from .models import Question ` ` 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) # render()은 1. request를 받고/ 2. template 이름을 받고, 3. context(이건 옵셔널임 -> 근데 결국 인수로 지정된 context로 표현된 템플릿의 HttpResponse 객체가 반환)
- 모든 뷰에 적용한다면, loader와 HttpResponse를 import 안해도돼
- 근데
class detail, results, vote
에서stub 메소드
를 가지고 있다면, HttpResponseimport
유지해야해 ㅡ ㅡ
- 근데
stub 메소드
뭐야 ?
polls/views.py
에서 excetp문
추가 시키자~~from django.http import Http404
from django.shortcuts import render
from .models import Question
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) # 2. question_id를 pk로 받고 Question을 조회를 했을때 데이터가 없으면
except Question.DoesNotExist: # 1. question에 데이터가 없는경우
raise Http404("Question does not exist") # 3. 이게 보여질 것이다!
return render(request, 'polls/detail.html', {'question': question})
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)
polls/templates/polls/detail.html
또한 같이 수정 ! !{{ question }}
- 지름길이 또 이써 ^^
get_object_or_404()
사용from django.http import HttpResponse, Http404 from django.template import loader from django.shortcuts import get_object_or_404, render # 추가 했지 ? ` from .models import Question ` 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): 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)
polls/templates/polls/detail.html
함보고 코드 추가하자<h1>{{ question.question_text }}</h1> # Django는 먼저 question 객체에 대해 사전형으로 탐색
<ul>
{% for choice in question.choice_set.all %} # 메소드 호출 question.choice_set.all = question.choice_set.all()처럼 사용됨
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
polls/index.html
template에 링크를 넣으면, 이 링크는 부분적으로 하드코딩된다 . !{% 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 %}
polls.urls
모듈의 path()
함수에서 인수의 이름을 정의했으므로, {% url %}
template
태그를 사용해서 url 설정에 정의된 특정한 URL 경로들의 의존성을 제거할 수 있다. ?? ?뭔말인지 나도 몰겠음{% url %}
template
태그를 사용해서 url경로 의존성을 제거 할 수 있다 ! 라고 기억이나 하자{% url %}
이걸 써서 바꿔보자{% 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 %}
polls.urls
모듈에 있는 URL
을 탐색하는 한다고 생각해 detail.py
의 URL
이 어떻게 되어있길래 위 코드로 탐색한다는 겨path('<int:question_id>/', views.detail, name='detail'), # 이 줄의 'name'과 template tag의 {% url %} 과 같다고 생각해
URL
을 polls/specifics/12/
로 바꾸고 싶다면, polls/urls.py에서 바꿔라 path('specifics/<int:question_id>/', views.detail, name='detail'), # 앞에 specifics를 추가해주면 깰끔
url
을 어떻게 구별 하지 ?urls.py
에 다가 이름을 넣어주면 돼 ! 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>/results/', views.results, name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
polls/templates/polls/index.html
에서도 detail
앞에 이름 딱 써주면 좋아<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
오늘은 여기까지 ㅡ ㅡ