Django/inflearn

삭제 시 비밀번호 적용하기

곽수진 2022. 12. 10. 02:54
반응형

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('restaurant/<int:id>/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")
]

▶ 기존 delete 메소드에서 GET으로 접근하면 비밀번호 입력 화면이 뜨고, POST로 접근하면 비밀번호를 검증 후에 삭제하도록 함

▶ delete 메소드에서 id를 직접 받을 수 있게 path parameter 수정

 

 

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, UpdateRestaurantForm
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'))
        password = request.POST.get('password', '')
        form = UpdateRestaurantForm(request.POST, instance=item)
        if form.is_valid() and password == item.password:
            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, id):
    item = get_object_or_404(Restaurant, pk=id)
    if request.method == 'POST' and 'password' in request.POST:
        if item.password == request.POST.get('password'):
            item.delete()
            return redirect('list')
        return redirect('restaurant-detail', id=id)
    return render(request, 'third/delete.html', {'item':item})


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)

if item.password == request.POST.get('password') : 입력한 비밀번호가 기존에 저장된 비밀번호와 동일한지 확인

 

 

{% extends 'third/base.html' %}
{% load static %}
{% block content %}
<div class="container">
  <div class="row">
    <div class="col-sm-12" style="margin-top:20px;">
      <h3>{{ item.name }}</h3>
      <p>
        {{ item.address }}
      </p>
      <p>
        <a href="{% url 'restaurant-delete' id=item.id %}">
          <button class="btn btn-danger">삭제하기</button>
        </a>
      </p>
      <hr/>
      <p>
        <a href="{% url 'review-create' restaurant_id=item.id %}">
          <button class="btn btn-info">리뷰쓰기</button>
        </a>
      </p>
      {% for review in reviews %}
      <div class="card bg-light mb-3">
        <div class="card-header">
          <b>{{ review.point }}</b>점
          <a href="{% url 'review-delete' restaurant_id=item.id review_id=review.id %}">
            <button type="button" class="close" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </a>
        </div>
        <div class="card-body">
          <p class="card-text">{{ review.comment }}</p>
        </div>
      </div>
      {% endfor %}
    </div>
  </div>
</div>
{% endblock %}

▶ 기존에 존재하던 detail.html 파일에서 삭제하기 버튼의 경로 수정

 

 

{% extends 'third/base.html' %}
{% load static %}
{% block content %}
<div class="container">
    <form action="{% url 'restaurant-delete' id=item.id %}" method="post">
        {% csrf_token %}
        <p>
            <label for="password">비밀번호</label>
            <input name="password" type="password"/>
        </p>
        <button type="submit">삭제</button>
    </form>
</div>
{% endblock %}

▶ 비밀번호 입력 페이지인 delete.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, UpdateRestaurantForm
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'))
        password = request.POST.get('password', '')
        form = UpdateRestaurantForm(request.POST, instance=item)
        if form.is_valid() and password == item.password:
            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, id):
    item = get_object_or_404(Restaurant, pk=id)
    if request.method == 'POST' and 'password' in request.POST:
        if item.password == request.POST.get('password') or item.password is None:
            item.delete()
            return redirect('list')
        return redirect('restaurant-detail', id=id)
    return render(request, 'third/delete.html', {'item': item})


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)

▶ 비밀번호 없이 저장되었던 게시글의 경우 비밀번호가 맞지 않아도 삭제되도록 구현

 

 

리스트 화면

 

 

마지막 게시글 detail 화면

 

 

삭제하기 버튼 클릭 후 delete 화면

 

 

비밀번호를 맞게 입력하고 list로 돌아온 화면

반응형