반응형
from django.shortcuts import render, get_object_or_404, redirect
from third.models import Restaurant, Reviews
from django.core.paginator import Paginator
from third.forms import RestaurantForm, ReviewForm
from django.http import HttpResponseRedirect
# Create your views here.
def list(request):
restaurants = Restaurant.objects.all()
paginator = Paginator(restaurants, 5)
page = request.GET.get('page')
items = paginator.get_page(page)
context = {
'restaurants': items
}
return render(request, 'third/list.html', context)
def create(request):
if request.method == 'POST':
form = RestaurantForm(request.POST)
if form.is_valid():
new_item = form.save()
return HttpResponseRedirect('/third/list/')
form = RestaurantForm()
return render(request, 'third/create.html', {'form': form})
def update(request):
if request.method == 'POST' and 'id' in request.POST:
# item = Restaurant.objects.get(pk=request.POST.get('id'))
item = get_object_or_404(Restaurant, pk=request.POST.get('id'))
form = RestaurantForm(request.POST, instance=item)
if form.is_valid():
item = form.save()
elif request.method == 'GET':
# item = Restaurant.objects.get(pk=request.GET.get('id'))
item = get_object_or_404(Restaurant, pk=request.GET.get('id'))
form = RestaurantForm(instance=item)
return render(request, 'third/update.html', {'form': form})
return HttpResponseRedirect('/third/list/')
def detail(request, id):
if 'id' is not None:
item = get_object_or_404(Restaurant, pk=id)
reviews = Reviews.objects.filter(restaurant=item).all()
return render(request, 'third/detail.html', {'item': item, 'reviews': reviews})
return HttpResponseRedirect('/third/list/')
def delete(request):
if 'id' in request.GET:
item = get_object_or_404(Restaurant, pk=request.GET.get('id'))
item.delete()
return HttpResponseRedirect('/third/list/')
def review_create(request, restaurant_id):
if request.method == 'POST':
form = ReviewForm(request.POST)
if form.is_valid():
new_item = form.save()
return redirect('restaurant-detail', id=restaurant_id)
item = get_object_or_404(Restaurant, pk=restaurant_id)
form = ReviewForm(initial={'restaurant': item})
return render(request, 'third/review_create.html', {'form': form, 'item': item})
def review_delete(request, restaurant_id, review_id):
item = get_object_or_404(Reviews, pk=review_id)
item.delete()
return redirect('restaurant-detail', id=restaurant_id)
def review_list(request):
reviews = Reviews.objects.all().order_by('-created_at')
paginator = Paginator(reviews, 10)
page = request.GET.get('page')
items = paginator.get_page(page)
context = {
'reviews': items
}
return render(request, 'third/review_list.html', context)
▶ paginator = Paginator(reviews, 10) : 한 페이지에 10개씩 표시
▶ page = request.GET.get('page') : query params에서 page 데이터를 가져옴
▶ items = paginator.get_page(page) : 해당 페이지의 아이템으로 필터링
{% extends 'third/base.html' %}
{% load static %}
{% block content %}
<div class="container">
{% for item in reviews %}
<div class="row restaurant-item" style="margin:20px auto">
<div class="card border-secondary">
<div class="card-body">
<h5 class="card-title">{{ item.restaurant.name }}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{ item.restaurant.address }}</h6>
<p class="card-text">{{ item.point }}점 / {{ item.comment }}</p>
</div>
</div>
</div>
{% endfor %}
<div class="row">
<div class="col-sm-12 text-center">
<div class="pagination">
<span class="step-links text-center" style="width:100%;">
{% if reviews.has_previous %}
<a href="?page=1">«</a>
<a href="?page={{ reviews.previous_page_number }}">{{ reviews.previous_page_number }}</a>
{% endif %}
<span class="current">
{{ reviews.number }}
</span>
{% if reviews.has_next and reviews.next_page_number != reviews.paginator.num_pages %}
<a href="?page={{ reviews.next_page_number }}">{{ reviews.next_page_number }}</a>
<a href="?page={{ reviews.paginator.num_pages }}">{{ reviews.paginator.num_pages }}</a>
{% elif reviews.has_next and reviews.next_page_number == reviews.paginator.num_pages %}
<a href="?page={{ reviews.next_page_number }}">{{ reviews.next_page_number }}</a>
{% endif %}
</span>
</div>
</div>
</div>
</div>
{% endblock %}
▶ 리뷰 목록을 가져올 review_list.html 파일 생성
▶ {{ item.restaurant.(Restaurant 모델에 정의된 속성) }} : Review와 Restaurant의 relation이 models.py에 정의되어 있기 때문에 리뷰 데이터에 연관된 음식점의 데이터에 접근할 수 있음
from django.urls import path
from . import views
urlpatterns = [
path('list/', views.list, name="list"),
path('create/', views.create, name="restaurant-create"),
path('update/', views.update, name="restaurant-update"),
# path('detail/', views.detail, name="restaurant-detail"),
path('delete/', views.delete, name="restaurant-delete"),
path('restaurant/<int:id>/', views.detail, name="restaurant-detail"),
path('restaurant/<int:restaurant_id>/review/create', views.review_create, name="review-create"),
path('restaurant/<int:restaurant_id>/review/delete/<int:review_id>', views.review_delete, name="review-delete"),
path('review/list', views.review_list, name="review-list")
]
▶ urls.py 파일에 review_list 화면을 연결
{% load static %}
<html>
<head>
<meta charset="UTF-8">
<title>음식점</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="stylesheet" href="{% static 'third/styles.css' %}">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.3/dist/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/third/list">음식점</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/third/list">리스트</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/third/create">등록</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/third/review/list">리뷰 리스트</a>
</li>
</ul>
</div>
</nav>
{% block content %}
{% endblock %}
</body>
</html>
▶ 기존에 있던 base.html 파일에 리뷰 리스트 링크 추가
from django.shortcuts import render, get_object_or_404, redirect
from third.models import Restaurant, Reviews
from django.core.paginator import Paginator
from third.forms import RestaurantForm, ReviewForm
from django.http import HttpResponseRedirect
# Create your views here.
def list(request):
restaurants = Restaurant.objects.all()
paginator = Paginator(restaurants, 5)
page = request.GET.get('page')
items = paginator.get_page(page)
context = {
'restaurants': items
}
return render(request, 'third/list.html', context)
def create(request):
if request.method == 'POST':
form = RestaurantForm(request.POST)
if form.is_valid():
new_item = form.save()
return HttpResponseRedirect('/third/list/')
form = RestaurantForm()
return render(request, 'third/create.html', {'form': form})
def update(request):
if request.method == 'POST' and 'id' in request.POST:
# item = Restaurant.objects.get(pk=request.POST.get('id'))
item = get_object_or_404(Restaurant, pk=request.POST.get('id'))
form = RestaurantForm(request.POST, instance=item)
if form.is_valid():
item = form.save()
elif request.method == 'GET':
# item = Restaurant.objects.get(pk=request.GET.get('id'))
item = get_object_or_404(Restaurant, pk=request.GET.get('id'))
form = RestaurantForm(instance=item)
return render(request, 'third/update.html', {'form': form})
return HttpResponseRedirect('/third/list/')
def detail(request, id):
if 'id' is not None:
item = get_object_or_404(Restaurant, pk=id)
reviews = Reviews.objects.filter(restaurant=item).all()
return render(request, 'third/detail.html', {'item': item, 'reviews': reviews})
return HttpResponseRedirect('/third/list/')
def delete(request):
if 'id' in request.GET:
item = get_object_or_404(Restaurant, pk=request.GET.get('id'))
item.delete()
return HttpResponseRedirect('/third/list/')
def review_create(request, restaurant_id):
if request.method == 'POST':
form = ReviewForm(request.POST)
if form.is_valid():
new_item = form.save()
return redirect('restaurant-detail', id=restaurant_id)
item = get_object_or_404(Restaurant, pk=restaurant_id)
form = ReviewForm(initial={'restaurant': item})
return render(request, 'third/review_create.html', {'form': form, 'item': item})
def review_delete(request, restaurant_id, review_id):
item = get_object_or_404(Reviews, pk=review_id)
item.delete()
return redirect('restaurant-detail', id=restaurant_id)
def review_list(request):
reviews = Reviews.objects.all().select_related().order_by('-created_at')
paginator = Paginator(reviews, 10)
page = request.GET.get('page')
items = paginator.get_page(page)
context = {
'reviews': items
}
return render(request, 'third/review_list.html', context)
▶ review 조회 시에 바로 join을 사용해서 restaurant 가져오기
▶ 기존에 구현했던 방식은 실제로 join을 하지 않기 때문에 item.restaurnat을 호출할 때마다 연관된 음식점 데이터를 조회하는 쿼리문이 리뷰의 개수만큼 수행되어 사이트가 느려질 수 있음
▶ Django ORM에서 데이터를 조회할 때 .select_related() 메소드를 추가로 호출하면 됨
반응형
'Django > inflearn' 카테고리의 다른 글
생성, 수정 Form에 비밀번호 입력 적용하기 (0) | 2022.12.09 |
---|---|
기존 모델에 새 컬럼(필드) 추가하기 (0) | 2022.12.08 |
리스트 화면에서 리뷰 개수와 평점 구하기 (0) | 2022.12.06 |
Join 개요 (0) | 2022.12.05 |
리뷰 삭제 구현하기 (0) | 2022.12.04 |