03_Web

13_Django_게시물 작성/수정/삭제 기능

chuuvelop 2025. 2. 5. 17:50
728x90
01. 사진 게시물 작성기능
  • 사진 게시물을 사용자가 직접, 관리자 페이지를 거치지 않고 작성하는 기능 개발
# photo/photo_post.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Photo App</title>
</head>
<body>
    <!-- <h1><a href="/">홈으로 돌아가기</a></h1>  두 개 중 원하는 방식으로 하면 됨-->
     <!-- 앞에 /가 없으면 상대경로ㅡ 앞에 /가 있으면 절대경로 -->
    <h1><a href="{% url 'photo_list' %}">홈으로 돌아가기</a></h1>
    <section>
        <div>
            <h2>New Photo</h2>
            <form method="POST">
                <!-- csrf토큰은 보안때문에 사용하고 반드시 있어야함 -->
                {% csrf_token %} {{ form.as_p}}
                <button type="submit">완료!</button>
            </form>
        </div>
    </section>
</body>
</html>

 

  • form 은 작성자가 데이터를 입력하여 서버로 보내도록 도와주는 양식
    • 사용자는 이 양식을 채워서 POST 방식으로 요청을 보내면, 서버에서는 해당 요청을 받아 처리
  • csrf_token : 글을 입력하는 폼에 악의적인 코드가 숨겨 있어
    • 사용자가 원하지 않는 글을 작성하도록 하는 보안 취약점을 방지하기 위한 보안 토큰
    • 사용자의 세션에 있는 토큰과 요청으로 들어온 토큰이 일치하는지 확인하여 방지
    • 쉽게 말하면 POST 요청의 보안을 지켜주는 도구
  • form.as_p : 우리가 만들 form을 p태그 형식으로 만들겠다
# photo/forms.py

from django import forms
from photo.models import Photo

class PhotoForm(forms.ModelForm):
    class Meta:
        model = Photo
        fields = (
            "title",
            "author",
            "image",
            "description",
            "price",
        )

 

# photo/views.py

from django.shortcuts import render, get_object_or_404, redirect
from photo.models import Photo
from photo.forms import PhotoForm

...

def photo_post(request):
    if request.method == "POST":
        form = PhotoForm(request.POST)
        if form.is_valid():
            photo = form.save(commit=False)
            photo.save()
            return redirect("photo_detail", pk = photo.pk)
        
    else:
        form = PhotoForm()

    context = {"form" : form}
    return render(request, "photo/photo_post.html", context)
  • redirect : 새로운 페이지로 이동시켜주는 함수
  • 조건문으로 들어온 요청이 POST인지 확인
    • 일반적으로 웹 브라우저에서 페이지로 접속하는 요청은 GET이기 때문에 POST를 보냈다는 것은
    • 템플릿의 폼의 제출 버튼이 눌러졌다는 뜻
    • 요청으로 들어온 폼 데이터를 form이라는 변수에 받아와 폼에 맞춰 잘 작성된 데이터인지 검사(is_valid())
    • 검사 결과 잘 작성되었다면 photo 라는 변수에 form에서 나온 데이터를 받아와 photo.save()로 저장
    • 이 때 데이터베이스에 해당 데이터가 저장됨
    • 저장을 마친 후 해당 게시글의 상세 페이지로 이동(새롭게 저장된 photo의 pk로)
  • 만약 POST요청이 아니라면 새롭게 해당 페이지로 들어온 사용자라는 뜻
    • 폼을 제공해야함
    • form을 선언하고 render() 함수로 템플릿의 photo_post.html과 form을 넘겨 주어, 사용자가 입력할 수 있는 화면을 보여줌
  • 만약에 검사 결과 잘 작성되지 않은 경우라면 render()로 빈 폼 페이지를 다시 보여주게 됨
# photo/urls.py

urlpatterns = [
    path("", views.photo_list, name="photo_list"),
    path("photo/<int:pk>/", views.photo_detail, name = "photo_detail"),
    path("photo/new/", views.photo_post, name = "photo_post"),
]

 

# photo_list.html

<body>
        <h1><a href="">사진 목록 페이지</a></h1>
         <h3><a href="{% url 'photo_post' %}">New Photo</h3>
        <section>

 

 

02. 사진 게시물 수정 기능
  • 게시물 작성과 상당히 유사
  • 기존 데이터가 폼에 있는 상태에서 입력하면 수정
  • 폼에 데이터만 채우면 그대로 수정이기 때문에 폼을 그대로 이용
    • photo_post.html 그대로 이용
# photo/views.py

def photo_edit(request, pk):
    photo = get_object_or_404(Photo, pk = pk)
    if request.method == "POST":
        form = PhotoForm(request.POST, instance = photo)
        if form.is_valid():
            photo = form.save(commit = False)
            photo.save()
            return redirect("photo_detail", pk = photo.pk)
        
    else:
        form = PhotoForm(instance = photo)

    context = {"form" : form}
    return render(request, "photo/photo_post.html", context)

 

  • POST인지 GET인지 판단하여 수정을 의미하는 POST요청이 왔을 때 폼으로 전달된 데이터를 판단
  • instance를 photo로 설정해주어 수정 대상이 될 데이터를 설정
  • GET 요청이 오더라도 photo데이터를 폼에 담아서 photo_post.html에 넘겨주어 기존 데이터를 수정할 수 있도록 처리
#photo/urls.py

urlpatterns = [
    path("", views.photo_list, name="photo_list"),
    path("photo/<int:pk>/", views.photo_detail, name = "photo_detail"),
    path("photo/new/", views.photo_post, name = "photo_post"),
    path("photo/<int:pk>/edit/", views.photo_edit, name = "photo_edit"),
]

 

 

03. 사진 게시물 삭제 기능

 

# views.py

def photo_delete(request, pk):
    photo = get_object_or_404(Photo, pk = pk)
    photo.delete()
    return redirect("photo_list")
# urls.py

urlpatterns = [
    path("", views.photo_list, name="photo_list"),
    path("photo/<int:pk>/", views.photo_detail, name = "photo_detail"),
    path("photo/new/", views.photo_post, name = "photo_post"),
    path("photo/<int:pk>/edit/", views.photo_edit, name = "photo_edit"),
    path("photo/<int:pk>/delete/", views.photo_delete, name = "photo_delete"),
]
728x90

'03_Web' 카테고리의 다른 글

15_검색기능이 되는 화면 만들기  (2) 2025.02.06
14_VIEW, URL, Template  (1) 2025.02.06
12_Django_상세보기 페이지 만들기  (0) 2025.02.05
11_Django_목록 화면 만들기  (0) 2025.02.05
10_Django_View, URL  (0) 2025.02.05