□ 앞에서 우리는 admin 페이지에서 게시물을 등록하고 게시된 것을 상세보는 것을 구현했음
□ 이번에는 admin이 아닌 사용자가 직접 게시물을 등록하도록 구현하고자함
□ 코드
○ T : Templete(템플릿) : 등록 페이지
- 등록 폼 : form 태그 + POST 방식 활용
※ POST, GET 방식
https://dandora-90.tistory.com/342
- csrf_token : CSRF(Cross-Site Request Forgery) 토큰은 웹 애플리케이션에서 사용자의 요청이 신뢰할 수 있는지 여부를 확인하기 위한 보안 기술 중 하나
https://dandora-90.tistory.com/321
<html>
<head>
<title>Photo App</title>
</haed>
<body>
<h1>
<a href="/">홈으로 돌아가기</a> <!--메인화면이동-->
</h1>
<div>
<section>
<h2>New Photo</h2>
<form method="POST"> <!-- form > POST 방식 지정 -->
{% csrf_token %}{{form.as_p}}
<button type="submit">등록</button>
</form>
</section>
</div>
</body>
</html>
○ form.py
- django 기본 ModelForm을 상속받아 아래의 필드값을 입력으로 받는 폼을 PhotoForm 클래스로 만듬
from django import forms
from .models import Photo
#app photo > model을 상속받아 아래 값을 입력받는 클래스 생성
class PhotoForm(forms.ModelForm):
class Meta:
model = Photo
fields =(
"title",
"author",
"image",
"description",
"price"
)
○ V : Views(뷰)
- 등록할 수 있는 photo_post 함수 정의
- POST방식으로 요청시, 위에서 정의한 PhotoForm에 입력된 값을 form에 저장 후 유효성 검사 진행
- 검사가 끝나면 이를 저장하도록 지정
(1) .save(commit=False) : 메모리에만 저장
(2) .save() : 데이터베이스 저장
- 저장이되면 등록한 게시글의 상세보기 페이지로 이동되도록 지정
from django.shortcuts import render, get_object_or_404, redirect #get_object_or_404 : 모델로부터 데이터를 찾아보고 만약 찾는 데이터가 없다면 404 에러 반환
from .models import Photo #orm을 활용해 app>photo 의 Photo 값을 호출
from .forms import PhotoForm #post 방식으로 받은 form 호출
#app photo 의 photo_list 함수 정의
def photo_list(request):
#app photo > model에서 정의한 클래스를 .object.all()로 모두 가져와 photos에 담음. photos는 템플릿파일에 활용됨.
photos = Photo.objects.all()
return render(request, "photo/photo_list.html",{"photos":photos})
#app photo 의 photo_detail 함수 정의
def photo_detail(request,pk):
photo = get_object_or_404(Photo, pk=pk)
return render(request,"photo/photo_detail.html", {"photo":photo})
#새글 등록 : post 방식 : 리다이렉트 및 페이지 이동
def photo_post(request):
if request.method == "POST": #html에서의 form 이 post 방식으로 서버가 요청올 경우
form = PhotoForm(request.POST) #forms.py에서 지정한 PhotoForm 클래스 가 호출되고 form 변수에 담김
if form.is_valid(): #.is_valid 유효성 검사 / 폼이 유효하지 않으면 추가적인 작업을 수행하지 않고 사용자에게 오류를 보여줌
photo=form.save(commit=False)
#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})
○ URL
- photo_post name이 호출되면 photo_new로 이동되도록 지정
from django.urls import path
from . import views
#app photo > view에서 정의한 photo_list 함수
urlpatterns = [
#"" 은 settings.py 에서 허용한 주소가 기본으로 들어감
path("", views.photo_list, name="photo_list"),
#models pk 정수형으로 들어가야하므로 <int:pk>
path("photo/<int:pk>/", views.photo_detail, name="photo_detail"), #상세보기
path("photo/new/", views.photo_post,name="photo_post"), #새글 등록
]
- 템플릿 파일에서 Photo 등록 버튼을 클릭하면 photo_post name에 따른 url로 이동되고, view에서 정의한 photo_post 함수가 작동되도록구현
<html>
<head>
<title>Photo App</title>
</head>
<body>
<h1><a href="">사진 목록 페이지</a></h1>
<h3><a href="{% url "photo_post" %}">Photo 등록</a></h3>
<section>
<!--템플릿태그-->
{% for photo in photos %}
<div>
<p>{{photo.pk}} 번쨰</p>
<h2>
<a href="{% url 'photo_detail' pk=photo.pk %}">{{photo.title}}</a>
</h2>
<img src="{{photo.image}}" alt="{{photo.title}}" width="300" />
<p>{{photo.description}}</p>
<p>{{photo.author}}, {{photo.price}}</p>
</div>
{% endfor %}
</section>
</body>
</html>
'Python > Django Ⅱ' 카테고리의 다른 글
Todo : Create, Read (0) | 2024.05.15 |
---|---|
Django 게시물 수정하기 (0) | 2024.05.14 |
게시물 상세보기 페이지 구현 + get_object_or_404 (1) | 2024.05.14 |
V : View(뷰) (0) | 2024.05.03 |
T : Template(템플릿) (0) | 2024.05.03 |