[Python Django] 3-7. CBV UpdateView를 이용한 글 수정 기능구현

2022. 3. 26. 09:47Python/Django Framework

반응형

urls.py 추가

from django.urls import path

from board.views import BoardCreateView, BoardDetailView, BoardListView, BoardUpdateView

urlpatterns = [
    path('create/', BoardCreateView.as_view()),
    path('update/<int:pk>/', BoardUpdateView.as_view()), # 추가
    path('list/', BoardListView.as_view()),
    path('detail/<int:pk>/', BoardDetailView.as_view())
]

UpdateView

  • UpdateView는 두 가지 방식으로 처리할 수 있는데 filed를 이용한 방식과 form_class를 이용한 방식이다
  • field를 이용하여 간단하게 iterable 객체를 설정하면 설정한 모델에서 데이터를 가져와 필드를 생성해준다
  • 하지만 field를 이용한 방식은 clean() 처리가 안되기 때문에 clean이 필요할 때는 form_class를 불러와 사용을 한다

field를 이용한 방식

views.py 수정

class BoardUpdateView(UpdateView):
    model = Board
    form_class = BoardUpdateForm

    template_name = "board_update.html"

    def form_valid(self, form):
        user_id = self.request.session.get('user_id')
        if user_id:
            try:
                user = User.objects.get(pk=user_id)
            except User.DoesNotExist:
                return redirect("/user/login/")
        else:
            return redirect("/user/logout/")

        board = Board.objects.get(pk=self.kwargs.get("pk"))
        board.title = form.cleaned_data.get('title')
        board.contents = form.cleaned_data.get('contents')
        board.save()

        return super().form_valid(form)

    # pk를 이용하여 detail 페이지로 돌아갈 수 있게 success_url을 제어한다
    def get_success_url(self):
        pk = self.kwargs.get('pk')
        return f'/board/detail/{pk}'

form_class를 이용한 방식

views.py 수정

  • fileds 설정 부분이 사라지고 form_class를 설정해주는 부분 외에는 동일하다 
class BoardUpdateView(UpdateView):
    model = Board
    form_class = BoardUpdateForm # field 방식에서 field가 사라지고 class에서 field를 정의
    template_name = "board_update.html"

	# 나머지는 소스는 field 방식과 같다

forms.py 수정

  • 메타 정보에 모델과 필드 정보를 정의한다
  • 클래스 상속을 받을때 forms.Form이 아닌 ModelForm을 받는 것을 잊지 않는다
class BoardUpdateForm(forms.ModelForm):
    title = forms.CharField(
        max_length=256,
        label="제목",
        error_messages={'required': '제목을 입력해주세요'}
    )
    contents = forms.CharField(
        widget=forms.Textarea,
        label="내용",
        error_messages={'required': '내용을 입력해주세요'}
    )

    class Meta:
        model = Board
        fields = ('title', 'contents')

board_update.html 템플릿 생성

{% extends "base.html" %}
{% block contents %}
    <div class="row mt-5">
        <div class="col-12">
            <h1>목록</h1>
        </div>
    </div>
    <div class="row mt-5">
        <div class="col-12">
            <table class="table table-hover">
                <thead>
                <tr>
                    <th scope="col">글번호</th>
                    <th scope="col">제목</th>
                    <th scope="col">글쓴이</th>
                    <th scope="col">등록일</th>
                </tr>
                </thead>
                <tbody>
                {% for board in board_list %}
                    <tr scope="row">
                        <td>{{ board.id }}</td>
                        <td><a href="/board/detail/{{ board.id }}/">{{ board.title }}</a></td>
                        <td>{{ board.insert_user }}</td>
                        <td>{{ board.insert_date|date:"Y-m-d" }}</td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
        <div class="row col-12">
            <div class="col-4">
                {% if request.session.user_id %}
                    <a class="btn btn-outline-primary" href="/user/logout">로그아웃</a>
                {% else %}
                    <a class="btn btn-outline-primary" href="/user/login">로그인</a>
                {% endif %}

            </div>
            <div class="col-4">
                <nav>
                    <ul class="pagination  justify-content-center">
                        {% if page_obj.has_previous %}
                            <li class="page-item">
                                <a class="page-link" href="?p={{ page_obj.previous_page_number }}">&laquo;</a>
                            </li>
                        {% else %}
                            <li class="page-item disabled">
                                <a class="page-link" href="javascript:return false">&laquo;</a>
                            </li>
                        {% endif %}
                        {% for page_no in page_list %}
                            {% if page_no == page_obj.number %}
                                <li class="page-item active">
                                    <a class="page-link" href="javascript:return false">
                                        {{ page_no }}
                                    </a>
                                </li>
                            {% elif page_no != '…' %}
                                <li class="page-item">
                                    <a class="page-link" href="?p={{ page_no }}">
                                        {{ page_no }}
                                    </a>
                                </li>
                            {% endif %}
                            {{ page }}
                        {% endfor %}
                        {% if page_obj.has_next %}
                            <li class="page-item">
                                <a class="page-link" href="?p={{ page_obj.next_page_number }}">&raquo;</a>
                            </li>
                        {% else %}
                            <li class="page-item disabled">
                                <a class="page-link" href="javascript:return false">&raquo;</a>
                            </li>
                        {% endif %}
                    </ul>
                </nav>
            </div>
            <div class="col-4">
                <a href="/board/create/" class="btn btn-primary float-end">글쓰기</a>
            </div>
        </div>
    </div>
{% endblock %}
반응형