rooms/views.py
기존 작성된 코드를 근간으로 짜보겠숩니돠
...
def room_detail(request, pk):
return render(request, 'rooms/room_detail.html')
쿼리셋도 있는데 굳이 인스턴스를 바로 가져온다고요?
쿼리셋 여러개가 필요한개 아니라 현재 이시점에서는 인스턴스 하나만 가져오는게 더 효율적이겠쥬?!
즉 상품하나!를 딱 가져오는거에요.
참고로pk가 어디서 굴러 들어온 녀셕인지 알고 싶으면 클릭해서 알아보시면되요.(책 PK에요)
render
함수에서 context
명은 생략하고 중괄호로 작성가능해유~.
...
def room_detail(request, pk):
room = models.Room.objects.get(pk=pk)
return render(request, 'rooms/room_detail.html', context={'room':room})
스텝1에서 context 안에 있는 room을 room_detail.html
로 던져버렸어요.
여기서 해당 룸에 대한 모든 정보를 풀어 헤쳐버리면 되겠조?
{% extends 'base.html' %}
{% block page_name %}
HOME
{% endblock page_name %}
{% block content %}
<div>
<h1>{{room.name}}</h1>
<h2>${{room.price}}</h2>
<h3>{{room.description}}</h3>
</div>
<div>
<h2>By: {{room.host.username}}</h2>
{% if room.host.superhost %}
<h3>Superhost[O]</h3>
{% else %}
<h3>Superhost[X]</h3>
{% endif %}
<h2>Amenities</h2>
{% for a in room.amenities.all %}
<li>{{a}}</li>
{% endfor %}
<h2>Facilities</h2>
{% for f in room.facilities.all %}
<li>{{f}}</li>
<h2>House Rules</h2>
{% for h in room.house_rules.all %}
<li>{{h}}</li>
{% endfor %}
{% endfor %}
<div>
{% endblock content %}
아래 사진과 같이 무자비한 pk번호를 넣어서 조회한다면 우리 데이터베이스에 그런 방이 있을 확률이 있을까요? 십중팔구는 없조?!!!
그런것도 예외처리를 해줘야해요. 왜냐구요? 서버 터지면 안되니깐~
일단 reverse, redirect 임포트 해줄게요.
그리고 가장 아래에 있는 room_detail
함수에서 작성한것 처럼 try except
문으로 해당 모델에서 찾을수 없다면(get()
일때 가능) DoesNotExist
를 사용해서 예외처리를해줄거에요.
그리고 redirect함수안에 reverse함수를 적는데 이때 url string을 작성해줄게요.
그러면 namespace='core', name='home'으로 쭉쭉 다시 돌아가서 메인페이지로 연결되요.
rooms/views.py
from django.utils import timezone
from django.urls import reverse
from django.shortcuts import render, redirect
from django.views.generic import ListView
from rooms import models
class HomeView(ListView):
''' HomeView Definition '''
model = models.Room
paginate_by = 10
paginate_orphans = 5
ordering = 'created'
context_object_name = 'rooms'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
now = timezone.now()
context['now'] = now
return context
def room_detail(request, pk):
try:
room = models.Room.objects.get(pk=pk)
return render(request, 'rooms/room_detail.html', context={'room':room})
except models.Room.DoesNotExist:
return redirect(reverse('core:home'))
통상 프런트에서 URI 길게 작성되는 PK가 있으면 막아버려요. 서버에 발도 못되게 하는거조!
밀리의 서재의 경우에는 자바스크립트 경고창을 띄우더군요.
서버에서 말도안되게 기이이이이인 숫자를 연산처리하게 하면 당근 서바 자원을 잡아먹으니 연산을 못하게 애초에 막아야 하는게 당연한거조.
참고로 302 스테이터스 코드가 나오네요. 물론 제가 redirect함수를 써서 그렇겠지만요.
전 심심해서 했지만 상용서버에서 이러면 안되요~
def room_detail(request, pk):
try:
last_room = models.Room.objects.last()
if pk >last_room.pk:
return redirect(reverse('core:home'))
room = models.Room.objects.get(pk=pk)
return render(request, 'rooms/room_detail.html', context={'room':room})
except models.Room.DoesNotExist:
return redirect(reverse('core:home'))
우리의 서버는 똑똑 하더군요?
애초에 같이 놀 생각이 없게 414를 뱉어버렸어요.