본문 바로가기
파이썬/파이썬 장고

Django) 3편, 글 작성하는 방법(Views.py의 create 함수 가공하기)

by SeH_ 2023. 1. 15.
반응형

위 글은 생활코딩 유튜브를 참고하였습니다. 

 

1. Views.py 안 HTML Template에서 create를 선언합니다. 

 

def HTMLTemplate(articleTag):
    global topics
    ol = ''
    for topic in topics :
        ol += f'<li><a href ="/read/{topic["id"]}">{topic["title"]}</a></li>'
    return f'''
    <html>
    <body>
        <h1><a href = "/">Django</a></h1>
        <ol>
            {ol}
        </ol>
        {articleTag}
        <ul>
            <a href = "/create/">create</a>
        </ul>
    </body>
    </html>
    '''

2. Views.py 안 create 함수를 재지정합니다.

input 태그를 통해 글을 입력하는 화면을 구현합니다. 

def create(request):
    article = '''
        <p><input type = "text" name = "title" placeholder = "title"></p>
        <p><textarea name = "body" placeholder = "body"></textarea></p>
        <p><input type = "submit"</p>
    '''
    # textarea : 여러 줄 텍스트 입력할 때 사용됨 
    # input type = submit : 제출 버튼 클릭
    return HttpResponse(HTMLTemplate(article))

* input 태그는 닫지 않습니다!

* 키워드 입력 시, 이 키워드가 title이라는 이름을 가지게 되어 서버로 전송 되게 됩니다. 

 

3. 위 input 데이터를 서버로 보내기 위해 가공 단계를 거쳐야 합니다.

* 태그들을 form 태그로 감싸야합니다.

* form에 action 기능을 넣습니다.

submit을 눌렀을 때 보내고 싶은 서버의 path는 action 속성으로 넣어주면 됩니다.

 

def create(request):
    article = '''
        <form action = "/create/">
            <p><input type = "text" name = "title" placeholder = "title"></p>
            <p><textarea name = "body" placeholder = "body"></textarea></p>
            <p><input type = "submit"</p>
        </form>
    '''
    # textarea : 여러 줄 텍스트 입력할 때 사용됨 
    # input type = submit : 제출 버튼 클릭
    # submit을 눌렀을 때 보내고 싶은 서버의 path는 action 속성으로 넣어주면 됩니다. 
    return HttpResponse(HTMLTemplate(article))

 

4. POST 방식으로 전환

위와 같은 방식은 특정 글을 create 했을 때, url에 정보가 다 나와있어 100명이 해당 url을 클릭하면 100개의 똑같은 새로운 글이 첨가됨을 알 수 있습니다. 이 방식을 'GET 방식'이라고 합니다.

위 'GET 방식'을 'POST 방식'으로 전환을 해야 합니다. 

form 태그 안에 method = 'post'를 기입해 주면 되지요.

 

하지만 장고가 보안 문제로 이를 자체적으로 막아놨다고 해요. 

csrf_exempt를 import 하고, @csrf_exempt를 해당 함수 위에 적으면 됩니다. 

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def create(request):
    global nextID
    if request.method == 'GET' :

        article = '''
            <form action = "/create/" method = "post">
                <p><input type = "text" name = "title" placeholder = "title"></p>
                <p><textarea name = "body" placeholder = "body"></textarea></p>
                <p><input type = "submit"</p>
            </form>
        '''
        return HttpResponse(HTMLTemplate(article))
    elif request.method == 'POST':
        title = request.POST['title']
        body = request.POST['body']
        newTopic = {"id" : nextID,'title' : title, 'body':body}
        nextID +=1
        topics.append(newTopic)
        return HttpResponse(HTMLTemplate('AAA'))

아까랑 코드가 많이 달라졌는데요, 코드가 직관적이니 한번 훑어보시면 이해가 빠르실 겁니다! 

* 처음에 request.method 가 get이었다가, post로 수정이 되어집니다.

 

5. 생성 후 바로 생성된 페이지로 이동하는 코드입니다. redirect를 이용하지요.

from django.shortcuts import render,HttpResponse, redirect

@csrf_exempt
def create(request):
    global nextID
    if request.method == 'GET' :

        article = '''
            <form action = "/create/" method = "post">
                <p><input type = "text" name = "title" placeholder = "title"></p>
                <p><textarea name = "body" placeholder = "body"></textarea></p>
                <p><input type = "submit"</p>
            </form>
        '''
        return HttpResponse(HTMLTemplate(article))
    elif request.method == 'POST':
        title = request.POST['title']
        body = request.POST['body']
        newTopic = {"id" : nextID,'title' : title, 'body':body}
        url = '/read/'+str(nextID)
        nextID +=1
        topics.append(newTopic)
        return redirect(url)

 

전체 코드

from django.shortcuts import render,HttpResponse, redirect
import random
from django.views.decorators.csrf import csrf_exempt

# post 방식에서 생기는 에러 처리

nextID = 4

topics = [
{'id' : 1, 'title' :'routing', 'body' : 'Routing is...'},
{'id' : 2, 'title' :'view', 'body' : 'View is...'},
{'id' : 3, 'title' :'Model', 'body' : 'Model is...'},
]

def HTMLTemplate(articleTag):
    global topics
    ol = ''
    for topic in topics :
        ol += f'<li><a href ="/read/{topic["id"]}">{topic["title"]}</a></li>'
    return f'''
    <html>
    <body>
        <h1><a href = "/">Django</a></h1>
        <ol>
            {ol}
        </ol>
        {articleTag}
        <ul>
            <a href = "/create/">create</a>
        </ul>
    </body>
    </html>
    '''
def index(request):

    article = '''
    <h2>Welcome</h2>
    Hello,Django
    '''
    return HttpResponse(HTMLTemplate(article))


def read(request,id):
    global topics
    article = ''
    for topic in topics :
        if topic['id'] == int(id) :
            article = f'<h2>{topic["title"]}</h2>{topic["body"]}'
    return HttpResponse(HTMLTemplate(article))


@csrf_exempt
def create(request):
    global nextID
    if request.method == 'GET' :

        article = '''
            <form action = "/create/" method = "post">
                <p><input type = "text" name = "title" placeholder = "title"></p>
                <p><textarea name = "body" placeholder = "body"></textarea></p>
                <p><input type = "submit"</p>
            </form>
        '''
        return HttpResponse(HTMLTemplate(article))
    elif request.method == 'POST':
        title = request.POST['title']
        body = request.POST['body']
        newTopic = {"id" : nextID,'title' : title, 'body':body}
        url = '/read/'+str(nextID)
        nextID +=1
        topics.append(newTopic)
        return redirect(url)

댓글