본문 바로가기
BackEnd/Flask

[플라스크로 웹 애플리케이션 만들기] CRUD 구현

by kurooru 2022. 9. 28.
from flask import Flask, request, redirect
import random

app = Flask(__name__)


nextId = 4
# 추후 db로 변경하여 사용할 예정
topics = [
    {'id': 1, 'title': 'html', 'body': 'html is ...'},
    {'id': 2, 'title': 'css', 'body': 'css is ...'},
    {'id': 3, 'title': 'javascript', 'body': 'javascript is ...'},
]

# 템플릿을 가져오는 함수
def template(contents, content, id = None):
    
    contextUI = ''
    
    if id != None:
        contextUI = f'''
            <li><a href="/update/{id}/">update</a></li>
            <li><form action="/delete/{id}" method="POST"><input type="submit" value="delete"></form></li>
            
        '''
    # 파이썬의 리턴 값은 문자열 이여야 함!
    return f''' <!doctype html>
    <html>
        <body>
            <h1><a href='/'>WEB</a></h1>
            <ol>
                {contents}
            </ol>
            {content}
            <ul>
                <li><a href="/create/">create</a></li>
                {contextUI}
            <ul>
        <body>
    </html>
    '''

# 내용을 가져오는 함수
def getContents():
    # 빈 문자열을 만들어 준 후,
    liTags = ''

    # 기존 데이터에서 문자열을 받아 와 liTags에 추가
    for topic in topics:
        liTags = liTags + f'<li><a href="read/{topic["id"]}/">{topic["title"]}</a></li>'
    
    return liTags

# 메인 페이지의 라우터
@app.route('/')
def index():
    
    # 파이썬의 리턴 값은 문자열 이여야 함!
    return template(getContents(), '<h2>Welcome</h2>Hello, web')

@app.route('/create/', methods=['GET', 'POST']) # post 방식 사용하고 싶을 시 methods = ['GET', 'POST'] 추가해줘야함
def create():
    
    print('request.method', request.method)
    
    if(request.method == 'GET'):
    
        # form 태그 -> 정보를 서버로 전송
        # action -> 어떤 경로로 전송할 것인가
        # name -> 어떤 이름으로 전송할 것인가
        # 이와 같은 방식을 get 방식(URL을 통해 서버에 정보 전달)

        # method post로 설정 시 URL로 정보 전달 x -> 이를 post방식이라 함

        content = '''
            <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" value="create"></p>
            </form>
        '''

        return template(getContents(), content)
    
    # post 방식일 경우
    else:
        
        global nextId

        # 데이터 가져오기
        title = request.form['title']
        body = request.form['body']

        newTopic = {
            'id': nextId,
            'title': title,
            'body': body,
        }

        topics.append(newTopic)
        url = '/read/'+str(nextId)+'/'
        nextId += 1

        return redirect(url)

@app.route('/update/<int:id>/', methods=['GET', 'POST'])
def update(id):
    
    print('request.method', request.method)
    
    if(request.method == 'GET'):
        title = ''
        body = ''
        
        for topic in topics:
            if topic['id'] == id:
                title, body = topic['title'], topic['body']
                break

        content = f'''
            <form action="/update/{id}/" method="POST">
                <p><input type="text" name="title" placeholder="title" value="{title}"></p>
                <p><textarea name="body" placeholder="body">{body}</textarea></p>
                <p><input type="submit" value="update"></p>
            </form>
        '''

        return template(getContents(), content)
    
    else:
        
        global nextId

        title = request.form['title']
        body = request.form['body']

        for topic in topics:
            if id == topic['id']:
                topic['title'] = title
                topic['body'] = body
                break

        url = '/read/'+str(nextId)+'/'

        return redirect(url)

@app.route('/delete/<int:id>/', methods=['POST'])
def delete(id):
    for topic in topics:
        if id == topic['id']:
            topics.remove(topic)
            break
    return redirect('/')

@app.route('/read/<int:id>/')
def read(id):

    title = ''
    body = ''

    for topic in topics:
        if topic['id'] == id:
            title, body = topic['title'], topic['body']
            break

    # 파이썬의 리턴 값은 문자열 이여야 함!
    return template(getContents(), f'<h2>{title}</h2>{body}', id)

# 포트 번호 설정 가능, debug=True 설정 시 실시간 코드 반영
# 주의할 점 : 서비스 할 때에는 debug 모드로 실행하면 안됨!
app.run(port = 5001, debug = True)