Django/inflearn

U : 게시글 수정 구현하기

곽수진 2022. 11. 10. 01:08
반응형

from django.shortcuts import render
from third.models import Restaurant
from django.core.paginator import Paginator
from third.forms import RestaurantForm
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'))
        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'))
        form = RestaurantForm(instance=item)
        return render(request, 'third/update.html', {'form': form})

    return HttpResponseRedirect('/third/list/')

▶ views.py 파일에 update 메소드 추가

if request.method == 'POST' and 'id' in request.POST : 글을 작성할 때와 동일하게 메소드는 POST여야 하고 POST에 글 번호(id)가 존재하는 경우

item = Restaurant.objects.get(pk=request.POST.get('id')) : Restaurant 객체의 POST id 값을 받아와 item에 넣음

form = RestaurantForm(request.POST, instance=item) : request의 POST 데이터들을 바로 PostForm에 담고 instance의 인자(수정 대상)을 item으로 지정

    → item은 id(글 번호)와 동일하므로 수정 대상을 id로 지정한 것과 동일함

 

 

{% extends 'third/base.html' %}
{% load static %}
{% block content %}
<div class="container">
    <form action="{% url 'restaurant-update' %}" method="post">
        {% csrf_token %}
        <input type="hidden" name="id" value="{{ form.instance.id }}" />
        <table>
            {{ form.as_table }}
        </table>
        <button type="submit">수정 완료</button>
    </form>
</div>
{% endblock %}

▶ update.html 파일을 생성

<input type="hidden" name="id" value="{{ form.instance.id }}" /> : hidden type으로 instance에 담겨 있는 id를 불러옴

 

 

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")
]

▶ urls.py 파일에 update 경로 추가

 

 

'/update/?id=수정할 글 번호'에 접속한 모습

 

 

'/update/?id=수정할 글 번호'에 접속한 모습

▶ id값이 존재하지 않는 경로로 접속했을 때 나오는 화면(DoesNotExist 오류 발생)

 

 

from django.shortcuts import render, get_object_or_404
from third.models import Restaurant
from django.core.paginator import Paginator
from third.forms import RestaurantForm
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/')

▶ 존재하지 않는 id 값의 경로로 접속했을 때 DoesNotExist 오류 대신 404 에러가 뜨도록 수정

from django.shortcuts import get_object_or_404 : 존재하지 않는 경로로 접속했을 경우 404 에러가 뜨도록 하는 쟝고 템플릿

item = get_object_or_404(Restaurant, pk=request.POST.get('id')

item = get_object_or_404(Restaurant, pk=request.GET.get('id')

 : request가 POST 혹은 GET일 경우 'id'가 존재하지 않으면 404 에러가 뜸

 

 

존재하지 않는 id 경로로 접속했을 경우 404 에러가 뜨는 모습

 

 

{% 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">음식점 설명</p>
                    <a href="#" 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">&laquo;</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 %}

▶ 리스트에서 수정하기 버튼을 클릭했을 때 수정 경로로 이동하도록 수정

{% url 'restaurant-update' %}?id={{ item.id }} : url 경로는 urls.py 파일에 선언한 name인 restaurant-update로 선언하고 id 값은 item 인스턴스에 담긴 id 값으로 불러옴

 

 

/third/list에 접속한 모습

 

 

/third/update/?id=수정하고자 하는 글 번호로 접속한 모습

 

 

수정 완료 버튼을 클릭한 후 다시 리스트로 돌아왔을 때 이름과 주소가 수정된 모습

반응형

'Django > inflearn' 카테고리의 다른 글

D : 게시글 삭제 구현하기  (0) 2022.11.12
R : 게시글 상세 화면 구현하기  (0) 2022.11.11
C : 게시글 등록 구현하기  (0) 2022.11.09
R : 페이지 구현하기  (0) 2022.11.08
R : 리스트 구현하기  (0) 2022.11.07