본문 바로가기
Python/Django Ⅱ

Django Form 기능 / 게시물 등록하기

by Mr.DonyStark 2024. 5. 14.

□ 앞에서 우리는 admin 페이지에서 게시물을 등록하고 게시된 것을 상세보는 것을 구현했음

이번에는 admin이 아닌 사용자가 직접 게시물을 등록하도록 구현하고자함

□ 코드

  ○ T : Templete(템플릿) : 등록 페이지

    - 등록 폼 : form 태그 + POST 방식 활용

     ※ POST, GET 방식

https://dandora-90.tistory.com/342

 

Get / Post 방식

1. 기본개념 : get 과 post 는 HTTP 프로토콜을 통해서 서버에 어떤 값을 전달 할 때 사용하는 방식의 종류. 즉, 어떻게 전달하나의 차이.2. 기본차이 : URL에 파라미터 값으로 데이터를 전달하면 Get방

dandora-90.tistory.com

    - csrf_token : CSRF(Cross-Site Request Forgery) 토큰은 웹 애플리케이션에서 사용자의 요청이 신뢰할 수 있는지 여부를 확인하기 위한 보안 기술 중 하나

https://dandora-90.tistory.com/321

 

CSRF_TOKEN 과 DB 입출력

□ 장고는 CSRF (Cross Site Request Forgery)와 위조방지를 위해 자체적으로 토큰을 발행하는데 이를 CSRF_TOKEN 이라고 함. □ 반드시 데이터를 요청할 때, 즉, 사용자의 request가 발생하면 이와 함께 CSRTF_TOK

dandora-90.tistory.com

<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