[django] FBV about product detail page

Hyeseong·2021년 2월 7일
0

django

목록 보기
31/35

상품 상세 페이지 FBV로 짜기😘

rooms/views.py

기존 작성된 코드를 근간으로 짜보겠숩니돠

...
def room_detail(request, pk):
    
    return render(request, 'rooms/room_detail.html')

스텝1, 디비에서 인스턴스 가져오기!😉

쿼리셋도 있는데 굳이 인스턴스를 바로 가져온다고요?
쿼리셋 여러개가 필요한개 아니라 현재 이시점에서는 인스턴스 하나만 가져오는게 더 효율적이겠쥬?!
즉 상품하나!를 딱 가져오는거에요.

참고로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})

스텝2, 템플릿 작성하기😉

스텝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 %}

스텝3, 없는방 조회하기😉

아래 사진과 같이 무자비한 pk번호를 넣어서 조회한다면 우리 데이터베이스에 그런 방이 있을 확률이 있을까요? 십중팔구는 없조?!!!
그런것도 예외처리를 해줘야해요. 왜냐구요? 서버 터지면 안되니깐~

try ... except... & 다른 페이지로 redirect 😶

일단 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'))

그런데 만약 위 숫자의 10배 이상으로 서버에 연산처리를 하게 해버리면?

우리의 서버는 똑똑 하더군요?

애초에 같이 놀 생각이 없게 414를 뱉어버렸어요.

profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글