반응형
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
from django.db.models import Count
# Create your views here.
def list(request):
restaurants = Restaurant.objects.all().annotate(reviews_count=Count('reviews'))
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)
▶ 각 음식점의 리뷰 수를 구하거나 평점을 음식점 목록 화면에서 바로 표시할 수 있도록 aggregation 이용
▶ Django ORM에서 제공하는 annotate 메소드는 조회되는 각 레코드들에 대해서 계산을 수행해 데이터를 뽑아낼 때 사용
.annotate(연산 결과를 저장할 속성명 = ORM 연산 메소드('relation 이름')
* Many-to-One 관계에서 부모 레코드에서 자식 레코드의 정보를 연산하는 경우 *
.annotate(연산 결과를 저장할 속성명 = ORM 연산('relation 이름__연산 대상 속성명')
{% extends 'third/base.html' %}
{% load static %}
{% block content %}
<div class="container">
{% for item in restaurants %}
<div class="row restaurant-item" style="margin:20px auto;">
<div class="col-sm-12">
<div class="card border-secondary">
<div class="card-body">
<h5 class="card-title">{{ item.name }}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{ item.address }}</h6>
<p class="card-text">리뷰: {{ item.reviews_count }}</p>
<p class="card-text">음식점 설명</p>
<a href="{% url 'restaurant-detail' id=item.id %}" class="card-link">자세히 보기</a>
<a href="{% url 'restaurant-update' %}?id={{ item.id }}" class="card-link">수정하기</a>
</div>
</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 restaurants.has_previous %}
<a href="?page=1">«</a>
<a href="?page={{ restaurants.previous_page_number }}">{{ restaurants.previous_page_number }}</a>
{% endif %}
<span class="current">
{{ restaurants.number }}
</span>
{% if restaurants.has_next and restaurants.next_page_number != restaurants.paginator.num_pages %}
<a href="?page={{ restaurants.next_page_number }}">{{ restaurants.next_page_number }}</a>
<a href="?page={{ restaurants.paginator.num_pages }}">{{ restaurants.paginator.num_pages }}</a>
{% elif restaurants.has_next and restaurants.next_page_number == restaurants.paginator.num_pages %}
<a href="?page={{ restaurants.next_page_number }}">{{ restaurants.next_page_number }}</a>
{% endif %}
</span>
</div>
</div>
</div>
</div>
{% endblock %}
▶ 기존의 list.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
from django.db.models import Count, Avg
# Create your views here.
def list(request):
restaurants = Restaurant.objects.all().annotate(reviews_count=Count('reviews'))\
.annotate(average_point=Avg('reviews__point'))
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)
▶ 기존 vies.py 파일의 list 메소드를 Avg를 추가해 수정
{% extends 'third/base.html' %}
{% load static %}
{% block content %}
<div class="container">
{% for item in restaurants %}
<div class="row restaurant-item" style="margin:20px auto;">
<div class="col-sm-12">
<div class="card border-secondary">
<div class="card-body">
<h5 class="card-title">{{ item.name }}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{ item.address }}</h6>
<p class="card-text">리뷰: {{ item.reviews_count }}, 평점: {{ item.average_point }}점</p>
<p class="card-text">음식점 설명</p>
<a href="{% url 'restaurant-detail' id=item.id %}" class="card-link">자세히 보기</a>
<a href="{% url 'restaurant-update' %}?id={{ item.id }}" class="card-link">수정하기</a>
</div>
</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 restaurants.has_previous %}
<a href="?page=1">«</a>
<a href="?page={{ restaurants.previous_page_number }}">{{ restaurants.previous_page_number }}</a>
{% endif %}
<span class="current">
{{ restaurants.number }}
</span>
{% if restaurants.has_next and restaurants.next_page_number != restaurants.paginator.num_pages %}
<a href="?page={{ restaurants.next_page_number }}">{{ restaurants.next_page_number }}</a>
<a href="?page={{ restaurants.paginator.num_pages }}">{{ restaurants.paginator.num_pages }}</a>
{% elif restaurants.has_next and restaurants.next_page_number == restaurants.paginator.num_pages %}
<a href="?page={{ restaurants.next_page_number }}">{{ restaurants.next_page_number }}</a>
{% endif %}
</span>
</div>
</div>
</div>
</div>
{% endblock %}
▶ 기존 list.html에 평점을 표현할 구문 추가 작성
반응형
'Django > inflearn' 카테고리의 다른 글
기존 모델에 새 컬럼(필드) 추가하기 (0) | 2022.12.08 |
---|---|
Join으로 모든 리뷰 리스트 불러오기 (0) | 2022.12.07 |
Join 개요 (0) | 2022.12.05 |
리뷰 삭제 구현하기 (0) | 2022.12.04 |
리뷰 등록 구현하기 (0) | 2022.12.03 |