[장고] 업데이트 뷰(Update View) - 모델 수정 작업 간편하게 만들기

소요 시간: 3분

장고에서 업데이트 뷰(Update View)를 구현하려면 UpdateView 클래스를 사용하면 됩니다. UpdateView는 사용자가 기존 모델 인스턴스를 업데이트할 수 있는 폼을 제공하는 제네릭 클래스 기반 뷰입니다.


업데이트 뷰

장고(Django)의 업데이트 뷰(UpdateView)는 모델의 기존 객체를 업데이트(수정)할 수 있도록 하는 클래스 기반 뷰(Class-Based View, CBV)입니다. 이를 사용하면 데이터를 쉽게 수정할 수 있는 웹 폼을 제공할 수 있습니다. 업데이트 뷰는 모델의 특정 인스턴스를 수정하는 폼을 자동으로 생성하고, 이를 처리하는 로직을 포함하고 있습니다.

주요 개념과 동작

주요 메서드

get_object(queryset=None):

수정할 객체를 반환합니다. 기본적으로 URL에서 추출된 pk나 slug를 사용합니다.

필요에 따라 이 메서드를 오버라이드하여 수정할 객체를 커스터마이징할 수 있습니다.

def get_object(self, queryset=None):
    obj = super().get_object(queryset)
    # 추가 로직 삽입 가능
    return obj

get_form_class():

사용할 폼 클래스를 반환합니다. form_class 속성을 설정하지 않으면 자동으로 모델 폼이 생성됩니다.

get_form_kwargs():

폼을 생성할 때 사용할 인수를 반환합니다. 이 메서드를 오버라이드하여 폼에 추가 데이터를 전달할 수 있습니다.

def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()
    kwargs['user'] = self.request.user
    return kwargs

form_valid(form):

폼이 유효할 때 호출됩니다. 폼을 저장하고 성공 URL로 리디렉션합니다.

def form_valid(self, form):
    # 추가 처리 로직 삽입 가능
    return super().form_valid(form)

form_invalid(form):

폼이 유효하지 않을 때 호출됩니다. 폼과 에러 메시지를 다시 렌더링합니다.

def form_invalid(self, form):
    # 추가 처리 로직 삽입 가능
    return super().form_invalid(form)


코드 구현

다음은 UpdateView를 사용하는 기본적인 예제입니다. 예를 들어, Review 모델의 정보를 업데이트하는 뷰를 만든다고 가정해보겠습니다.

모델 - 폼 - 업데이트 뷰 - URL설계 - 템플릿 작성으로 진행됩니다.

모델 정의

Review 모델은 리뷰의 제목, 내용, 작성자, 작성 날짜 등을 포함할 수 있습니다. 아래는 예시 Review 모델 정의입니다.

from django.db import models
from django.contrib.auth.models import User

class Review(models.Model):
    title = models.CharField(max_length=200)  # 리뷰 제목
    content = models.TextField()  # 리뷰 내용
    author = models.ForeignKey(User, on_delete=models.CASCADE)  # 작성자 (유저 모델과 연관)
    created_at = models.DateTimeField(auto_now_add=True)  # 작성 날짜 (자동 생성)
    updated_at = models.DateTimeField(auto_now=True)  # 수정 날짜 (자동 업데이트)

    def __str__(self):
        return self.title

Review 모델은 사용자 리뷰를 저장하는 Django 모델입니다. 이 모델은 리뷰의 제목, 내용, 작성자, 작성 날짜 및 수정 날짜를 포함합니다. 제목(title)은 최대 200자의 문자열로 저장되며, 내용(content)은 상세한 리뷰 내용을 저장하기 위한 텍스트 필드로 정의됩니다. 작성자(author)는 Django의 기본 User 모델과 외래 키 관계를 맺고 있으며, 작성자가 삭제될 경우 관련된 리뷰도 함께 삭제됩니다(on_delete=models.CASCADE).

또한, Review 모델은 작성 날짜(created_at)와 수정 날짜(updated_at)를 자동으로 기록합니다. 작성 날짜는 리뷰가 처음 생성될 때 현재 날짜와 시간을 저장하며(auto_now_add=True), 수정 날짜는 리뷰가 수정될 때마다 자동으로 업데이트됩니다(auto_now=True). 이 모델은 __str__ 메서드를 통해 관리자 인터페이스 등에서 객체를 문자열로 표현할 때 리뷰의 제목을 반환하도록 정의되어 있습니다. 이를 통해 사용자는 리뷰를 생성, 업데이트 및 삭제할 수 있습니다.

폼 정의 (forms.py)

ModelForm을 사용하여 Review 모델을 기반으로 한 폼을 정의합니다.

from django import forms
from .models import Review

class ReviewForm(forms.ModelForm):
    class Meta:
        model = Review
        fields = ['title', 'content']

ReviewForm 클래스는 Review 모델의 title과 content 필드를 포함합니다. 이를 통해 사용자는 리뷰의 제목과 내용을 입력할 수 있으며, 입력된 데이터는 Review 모델의 인스턴스를 생성하거나 업데이트하는 데 사용됩니다.

업데이트뷰

UpdateView를 사용하여 리뷰 객체를 업데이트하는 뷰를 정의합니다.

class ReviewUpdateView(UpdateView):
    model = Review
    context_object_name = 'review' #1
    form_class = ReviewForm
    template_name = 'reviews/review_update.html' #2
    success_url = '/' #3

    #get object
    def get_object(self): 
        review = get_object_or_404(Review, pk=self.kwargs['pk']) #4

        return review

#1 context_object_name = 'review':

이 속성은 템플릿에서 객체를 참조할 때 사용할 이름을 지정합니다. 여기서는 'review'로 설정하여 템플릿에서 review라는 이름으로 객체를 사용할 수 있게 합니다.

#2 template_name = 'reviews/review_update.html':

이 속성은 뷰가 렌더링할 템플릿 파일을 지정합니다. reviews/review_update.html 템플릿을 사용하여 폼을 렌더링합니다.

#3 success_url = reverse_lazy('index'):

이 속성은 폼이 성공적으로 제출된 후 리디렉션할 URL을 지정합니다. 여기서는 index 페이지로 리디렉션합니다.

#4 def get_object(self)::

이 메서드는 뷰가 업데이트할 객체를 가져오는 방법을 정의합니다. URL에서 전달된 pk 값을 사용하여 Review 객체를 검색하고, 이를 반환합니다.


URL 패턴 정의 (urls.py)

pk 값은 어디로부터 받을까? urls.py에서 확인해보자.

from django.urls import path
from . import views
    
urlpatterns = [
    path('review/<int:pk>/edit/', views.ReviewUpdateView.as_view(), name='review_edit'),
]

review/<int:pk>/edit/ 패턴은 ReviewUpdateView를 호출합니다. URL에서 pk 값을 추출하여 뷰에 전달합니다.

<h1>Update Review</h1>
<form method="post" action="{% url 'reviewBoard:review_edit' review.id %}">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save changes</button>
</form>

이 HTML 코드는 책 정보를 업데이트하는 폼을 제공하는 웹 페이지입니다. 페이지의 제목은 "Update Book"이며, 사용자가 책 정보를 수정할 수 있도록 폼을 제공합니다.

폼은 POST 메서드를 사용하여 데이터를 제출하며, action="{% url 'reviewBoard:review_edit' review.id %}": context_object_name을 review로 지정했으므로, review.id를 통해 URL에 pk 값을 전달합니다.

CSRF 공격을 방지하기 위해 {% csrf_token %} 태그를 포함하고 있습니다. 폼 필드는 Django 템플릿 언어를 사용하여 {{ form.as_p }}로 렌더링되며, 이는 폼 필드를 각기 다른 <p> 태그로 감싸서 표시합니다. 사용자가 정보를 입력하고 "Save changes" 버튼을 클릭하면, 폼 데이터가 서버로 제출됩니다.


전체적인 흐름


결론

Django의 업데이트 뷰를 사용하여 모델 인스턴스를 업데이트하는 과정을 설명했습니다. Review 모델은 제목, 내용, 작성자, 작성 날짜, 수정 날짜를 저장합니다. ReviewForm은 이 모델의 제목과 내용을 업데이트할 수 있는 폼을 제공합니다. ReviewUpdateView는 UpdateView를 상속받아 특정 리뷰 객체를 수정하는 뷰를 정의하며, URL 패턴을 통해 뷰에 접근할 수 있습니다. 템플릿은 폼을 렌더링하고 데이터를 제출할 때 적절한 URL로 전송하여 업데이트를 처리합니다. 이를 통해 사용자는 리뷰 정보를 쉽게 수정할 수 있으며, 애플리케이션은 효율적으로 데이터를 관리할 수 있습니다.

장고 리스트