ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Django] CRUD로 블로그 구현하기(CREATE)
    Python & Django 2021. 6. 1. 22:11

    계속해서 CRUD 중 create 기능을 구현해보도록 하겠습니다!


    1. Create 설계

    create 기능은 두 가지로 나뉘어집니다.

     

    1. 게시글을 작성하는 페이지(new)

    2. 작성한 데이터를 저장하는 기능(create)

     

    1번은 view 에서 게시물 작성 페이지(new.html)를 열어주고, 그 페이지에 데이터를 입력받을 폼을 생성합니다. 2번은 view 에서 폼에 입력한 데이터를 저장하는 기능을 만들어주면 됩니다.


    2. 게시글 작성 페이지(new)

    템플릿 만들기

    우선 templates 에 new.html 파일을 만들어 게시물 작성 페이지를 만들어줍니다.

     

    뷰 만들기

    그리고 view.py 에서 new 메소드를 만들어줍니다.

    def new(request):
        return render(request, 'new.html')

    view 에서 new 는 새로운 게시글을 만드는 페이지인 new.html 만 열어주면 됩니다.

     

    url 만들기

    ...
        path('new/', new, name="new"),
    ]

    url 도 앞에서 연결한 것과 같이 new/ 주소에, new 액션, name 을 지정해줍니다.

     

    템플릿 완성하기

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>New</title>
    </head>
    <body>
        <form action="">
            <label for="title">제목</label>
            <input type="text" id="title" name="title">
            <br>
            <label for="writer">작성자</label>
            <input type="text" id="writer" name="writer">
            <br>
            <label for="body">내용</label>
            <textarea name="body" id="body" cols="30" rows="10"></textarea>
            <button type="submit">제출</button>
        </form>
    </body>
    </html>

    new.html 에서 form 태그를 사용해 title, writer, body 를 입력할 폼을 만들어주고 submit 버튼을 만들어줍니다. 폼은 액션은 뒤에서 create 와 연결하도록 하겠습니다.

     

    여기서 input 의 name 속성 값을 컬럼과 일치하게 지정해줘야 해당 name 에 따라 views.py 의 create 액션에서 각 데이터를 컬럼에 맞게 넣어줄 수 있습니다.

     

    new 버튼 만들기(home.html)

    home.html 에서 새 글 쓰기 버튼(new)을 추가해 new.html 과 연결해줍니다. 이때 url 은 new 와 연결합니다.

    <h1>이구의 블로그</h1>
        <a href="{% url 'new' %}">새 글 쓰기</a> # 추가
        <hr>
        {% for blog in blogs %}
            ...
        {% endfor %}

    위 이미지처럼 home.html 에 새 글 쓰기 버튼이 만들어졌고, 버튼을 눌러보면 new 페이지가 정상적으로 나옵니다. 이제 계속해서 입력받은 데이터를 DB 에 저장하는 create 기능을 만들겠습니다.


    3. 저장 기능 만들기(create)

    일단, 저장 기능에서 create 템플릿이 따로 필요 없습니다. 폼에 데이터를 입력하고 제출 버튼을 눌렀을 때 views.py 의 create 메소드로 가서 해당 데이터를 데이터베이스에 저장해주기 때문입니다.

     

    뷰 만들기

    from django.shortcuts import render, get_object_or_404, redirect
    from django.utils import timezone
    ...
    
    # Create your views here.
    ...
    
    def create(request):
        new_blog = Blog()
        new_blog.title = request.POST['title']
        new_blog.writer = request.POST['writer']
        new_blog.body = request.POST['body']
        new_blog.pub_date = timezone.now()
        new_blog.save()
    
        return redirect('detail', new_blog.id)

    뷰의 코드는 위와 같습니다.

     

    가장 먼저 create 함수에 new_blog = Blog() 로 빈 객체를 생성합니다. Blog() 는 빈 객체를 생성하라는 의미입니다. new_blog.title = request.POST['title'] 은 new_blog 의 title 컬럼에는 request 와 함께 넘어온 데이터에서 title 에 해당하는 데이터를 담으라는 의미입니다.

     

    writer 와 body 는 title 과 동일한 방식이며 new_blog.pub_date = timezone.now() 는 pub_date 컬럼에는 현재 시간을 넣으라는 의미인데, timezone 을 사용하기 위해서는 맨 위에서 두번째 줄처럼 django.utils 에서 timzone 을 import 해야 합니다.

     

    그리고 컬럼들에 데이터를 넣었으면 save 메소드를 사용해 저장해줍니다.

     

    마지막으로 redirect 를 통해 detail 페이지로 가는데 지금 생성한 new_blog 객체에 해당하는 id 값을 넣어줘서 새로 만든 게시글의 상세 페이지로 이동시킵니다.

     

    redirect 도 사용하려면 django.shortcuts 에서 redirect 를 import 해야 합니다.

     

    url 만들기

    함수를 새로 만들었기 때문에 이 함수로 연결할 수 있는 url 을 만듭니다.

    urlpatterns = [
        ...
        path('create/', create, name="create"),
    ]

     

    new.html 완성하기

    이제 다시 new.html 에 가서 폼을 완성해줍니다. 

    <form action="{% url 'create' %}" method="POST"> # url, method 추가
            {% csrf_token %} # csrf 토큰 추가
            
            ...
    </form>

    우선 폼의 액션에는 views.py 의 create 함수로 전달하기 위해 방금 urls.py 에서 만든 create url 을 넣어주고, POST 메소드를 지정해줍니다.

     

    그리고 POST 방식으로 데이터를 보낼 때에는 csrf 공격을 방지하기 위한 token 을 넣어줘야 합니다.

     

    이제 서버를 실행해 잘 작동하는지 확인해보겠습니다.

    위 이미지처럼 입력받은 데이터를 잘 전달하고 보여주는 것을 볼 수 있습니다!


Designed by Tistory.