이전까지는 관리자 페이지를 거쳐서 게시물을 추가하였다. 이번에는 관리자 페이지를 거치지않고 사용자가 직접 게시물을 작성할 수 있도록 기능을 구현한다.
photo/photo_post.html 파일을 작성한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Photo App</title>
</head>
<body>
<h1><a href="/">홈으로 </a></h1>
<div>
<section>
<h2> New Photo</h2>
<form method="POST">
{% csrf_token %} {{ form.as_p }}
<button type="submit"> 완료 </button>
</form>
</section>
</div>
</body>
</html>
csrf_token
: 글 입력 폼에 악의적인 코드가 숨겨져 있어 사용자가 의도하지 않은 글을 작성하도록 하는 보안 취약점을 방지하기 위한 보안 토큰
사용자의 세션에 있는 토큰과 요청으로 들어온 토큰이 일치하는지 확인하여 해당 취약점을 방지한다.
간단히 말하자면 POST 요청의 보안을 위한 도구
form.as_p
: 폼을 태그 형식으로 만들어준다.
photo 앱 폴더 내에 forms.py 파일을 작성한다.
from django import forms
from .models import Photo
class PhotoForm(forms.ModelForm):
class Meta:
model = Photo
fields = (
'title',
'author',
'image',
'description',
'price'
)
django의 기본 ModelForm을 상속받아 아래의 필드 값을 입력받는 폼을 PhotoForm 클래스로 만든다.
from django.shortcuts import render, get_object_or_404, redirect
from .forms import PhotoForm
from .models import Photo
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()
return render(request, 'photo/photo_post.html', {'form':form})
if request.method == "POST"
들어온 요청이 POST인지 확인
form = PhotoForm(request.POST)
, form.is_valid()
들어온 폼 데이터를 form이라는 변수로 받아와서 폼 요구사항에 맞도록 작성된 데이터인지 확인
- 맞으면 DB에 저장 후 세부 페이지로 이동
- 아니면 다시 빈 폼 페이지를 렌더
사진 게시글 추가를 위한 링크 설정
path('photo/new/', views.photo_post, name='photo_post')
위 코드를 urlpatterns에 추가해준다.
<html>
<head>
<title>Photo App</title>
</head>
<body>
<h1><a href="">사진 목록 페이지</a></h1>
<!-- 코드 추가 -->
<h3><a href="{% url 'photo_post' %}">New Photo</a></h3>
<section>
<!--생략-->
서버 새로고침 후 New Photo 링크가 생성된다. 이를 클릭하면 폼 화면이 출력됨
완료 클릭하면 해당 사진이 새로 등록되면서 세부 화면 페이지로 이동한다.
이제 수정 기능 할게요?
나 티라미수 좀 먹고
게시글 작성이랑 비슷혀
템플릿은 게시글 작성 템플릿을 그대로 이용한다.
def photo_edit(request, pk):
photo = get_object_or_404(Photo, 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)
return render(request, 'photo/photo_post.html', {'form': form})
form = PhotoForm(request.POST, instance=photo)
path('photo/<int:pk>/edit/', views.photo_edit, name='photo_edit')
urlpatterns에 추가해준다. pk 값을 url에 넣어서 구분
<html>
<head>
<title>Photo App</title>
</head>
<body>
<h1>{{photo.title}}</h1>
<h3><a href="{% url 'photo_edit' pk=photo.pk %}">Edit photo</a></h3>
<section>
<div>
<img src="{{ photo.image }}"
alt="{{ photo.title }}"
width="300"/>
<p> {{ photo.description }}</p>
<p> {{ photo.author }}, {{ photo.price }}원</p>
</div>
</section>
</body>
</html>
크흡 개요 끝이다....