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 |