https://dev.to/themeselection/the-best-python-web-frameworks-d2d
The Best Python Web Frameworks 2024๐คฉ
Want to kickstart your journey as a Python developer? Then you are in the right place. Here you’ll...
dev.to
MVC (๋ชจ๋ธ-๋ทฐ-์ปจํธ๋กค๋ฌ) ๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค, ๋ฐ์ดํฐ ๋ฐ ๋ ผ๋ฆฌ ์ ์ด๋ฅผ ๊ตฌํํ๋๋ฐ ๋๋ฆฌ ์ฌ์ฉ๋๋ ์ํํธ์จ์ด ๋์์ธ ํจํด์ ๋๋ค. ์ํํธ์จ์ด์ ๋น์ฆ๋์ค ๋ก์ง๊ณผ ํ๋ฉด์ ๊ตฌ๋ถํ๋๋ฐ ์ค์ ์ ๋๊ณ ์์ต๋๋ค. ์ด๋ฌํ "๊ด์ฌ์ฌ ๋ถ๋ฆฌ" ๋ ๋๋์ ์ ๋ฌด์ ๋ถ๋ฆฌ์ ํฅ์๋ ๊ด๋ฆฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.


์ฐ์ ๋ฐฑ์๋๋ฅผ ๊ตฌ์ฑํ๊ธฐ ์ํด ํ์ํ ๊ตฌ์กฐ

# pip๋ฅผ ํตํด ์ต์ํ์ ๊ฐ์ํ๊ฒฝ์ ์์ฑํ๋ ๋ช
๋ น์ด
$ python -m venv myproject
๋ค์์ ํตํด myproject๋ผ๋ ๊ฐ์ํ๊ฒฝ์ ๋ง๋ ๋ค.
# myproject.cmd ์์ฑ
@echo off
set FLASK_APP=test
set FLASK_DEBUG=true
C:\ITStudy\09_flask\fisa-flask\myproject\Scripts\activate.bat
๋ค์์ ํตํด ๋ฐ๋ก init์ ์ฝ์ ์ ์๊ฒ ๋ง๋ ๋ค.
๊ฐ๋จํ๊ฒ ๋ฐฑ์๋ ๊ตฌ์ฑ
def create_app():
app = Flask(__name__)
# URL๊ณผ FLASK์ฝ๋๋ฅผ ๋งคํํ๋ Flask ๋ฐ์ฝ๋ ์ดํฐ
# @app.route์ฒ๋ผ ์ ๋
ธํ
์ด์
์ผ๋ก URL์ ๋งคํํ๋ ํจ์๋ฅผ ๋ผ์ฐํ
ํจ์๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
@app.route('/')
def hello():
return f'Hello, {__name__}'
@app.route('/jeongwoo')
def hello_jeongwoo():
return f'Hello, jeongwoo'
return app
## test/__init__.py
def create_app(): # ์ดํ๋ฆฌ์ผ์ด์
ํฉํ ๋ฆฌ - ํ๋ผ์คํฌ ์๋ฒ๊ฐ ์คํ๋ ๋ ๊ฐ์ฅ ์ต์ด๋ก ์คํ๋๋ ์์ฑ์
test = Flask(__name__)
# ORM
test.config.from_object(config)
db.init_app(test)
migrate.init_app(test, db)
# ๋ธ๋ฃจํ๋ฆฐํธ
from .views import main_views # views ํด๋ ๋ฐ์ main_views.py ์ํฌํธ
test.register_blueprint(main_views.bp)
return test
models.py ์์ฑ
from test import db
class Question(db.Model):
id = db.Column(db.Integer, primary_key=True)
subject = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text(), nullable=False)
create_date = db.Column(db.DateTime(), nullable=False)
class Answer(db.Model):
id = db.Column(db.Integer, primary_key=True)
question_id = db.Column(db.Integer, db.ForeignKey('question.id', ondelete='CASCADE'))
question = db.relationship('Question', backref=db.backref('answer_set'))
content = db.Column(db.Text(), nullable=False)
create_date = db.Column(db.DateTime(), nullable=False)
config.py
import os
BASE_DIR = os.path.dirname(__file__)
SQLALCHEMY_DATABASE_URI = 'sqlite:///{}'.format(os.path.join(BASE_DIR, 'test.db'))
SQLALCHEMY_TRACK_MODIFICATIONS = False
## flask shell
>>> from test.models import Question
>>> from datetime import datetime
>>> q = Question(subject="์ ๋ชฉ์
๋๋ค", content="๋ด์ฉ์
๋๋ค", create_date=datetime.now())
>>> q
<Question (transient 2955131385264)>
>>> from test import db
>>> db.session.add(q)
>>> db.session.commit()
>>> q
<Question 1>
>>> q.id
1
>>> q.content
'๋ด์ฉ์
๋๋ค'
>>> q.subject
'์ ๋ชฉ์
๋๋ค'
>>> Question.query.all()
[<Question 1>]
>>> Question.query.filter(Question.id==1).all()
[<Question 1>]
>>> q
ํธ๋ฌ๋ธ ์ํ
๋ค์ ํ๋๊น ๋๋ค..? update๋ฅผ ๋ค์ ํด์ฃผ๋๊น insert๊ฐ ๋จ
๋ค์๊ณผ ๊ฐ์ด ํ์ธ ๊ฐ๋ฅ

db ์ถ๊ฐ ๊ฐ๋ฅ

์ด๋ฐ์์ผ๋ก db์ ๋ด์ฉ์ ์ฐพ์ ์ ์์
>>> q = Question.query.get(2)
>>> q
<Question 2>
>>> q.subject
'์ ๋ชฉ์
๋๋ค2'
>>> q = Question.query.filter(Question.subject.like("%๋ ์จ%")).get()
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: Query.get() missing 1 required positional argument: 'ident'
>>> q = Question.query.filter(Question.subject.like("%๋ ์จ%")).all()
>>> q
[<Question 4>]
>>> q[0]
<Question 4>
>>> q[0].subject
'๋ ์จ๊ฐ ์ถ์์
๋๋ค'
>>> q[0].subject = "๋ ์จ๊ฐ ๋งค์ฐ ์ถฅ์ต๋๋ค"
>>> q[0].subject
'๋ ์จ๊ฐ ๋งค์ฐ ์ถฅ์ต๋๋ค'
>>> db.session.commit()
>>> q
[<Question 4>]
>>> db.session.delete(q)
Traceback (most recent call last):
File "C:\ITStudy\09_flask\fisa-flask\myproject\lib\site-packages\sqlalchemy\orm\session.py", line 3478, in delete
state = attributes.instance_state(instance)
AttributeError: 'list' object has no attribute '_sa_instance_state'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\ITStudy\09_flask\fisa-flask\myproject\lib\site-packages\sqlalchemy\orm\scoping.py", line 672, in delete
return self._proxied.delete(instance)
File "C:\ITStudy\09_flask\fisa-flask\myproject\lib\site-packages\sqlalchemy\orm\session.py", line 3480, in delete
raise exc.UnmappedInstanceError(instance) from err
sqlalchemy.orm.exc.UnmappedInstanceError: Class 'builtins.list' is not mapped
>>> db.session.delete(q[0])
>>> db.session.commit()
- ์ฌ๋ฌ๋ถ์ ์ด๋ฆ์ question ํ
์ด๋ธ์ content ์์ฑ์ ๋ฃ์ด์ 1๊ฐ ๊ธ์ ์์ฑํ์ธ์
- filter๋ฅผ ์ฌ์ฉํด์ ๊ทธ ๊ธ์ ๊ฐ์ ธ์๋ณด์ธ์
- ๊ธ์ content๋ฅผ '์ ์งฑ๊ตฌ'๋ก ๋ณ๊ฒฝํด๋ณด์ธ์
- ๊ทธ ๊ธ์ ์ญ์ ํด์ฃผ์ธ์
>>> db.session.delete(q[0])
>>> db.session.commit()
>>> a = Answer(question_id=1, content="1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค", create_date=datetime.now())
>>> a
<Answer (transient 2955131376432)>
>>> db.session.add(a)
>>> db.session.commit()
>>> a
<Answer 1>
>>> a.question_id
1
>>> a.question
<Question 1>
>>> a.question.content
'๋ด์ฉ์
๋๋ค'
>>> a.question.subject
'์ ๋ชฉ์
๋๋ค'
>>> q = a.question
>>> db.session.delete(q[0])
>>> db.session.commit()
>>> a = Answer(question_id=1, content="1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค", create_date=datetime.now())
>>> a
<Answer (transient 2955131376432)>
>>> db.session.add(a)
>>> db.session.commit()
>>> a
<Answer 1>
>>> a.question_id
1
>>> a.question
<Question 1>
>>> a.question.content
'๋ด์ฉ์
๋๋ค'
>>> a.question.subject
'์ ๋ชฉ์
๋๋ค'
>>> q = a.question
>>> q.answer_set
[<Answer 1>]
>>> a = Answer(question_id=1, content="๋๋ฒ์งธ 1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค", create_date=datetime.now())
>>> a
<Answer (transient 2955131818416)>
>>> db.session.add(a)
>>> db.session.commit()
>>> q.answer_set
[<Answer 1>, <Answer 2>]
>>> q.answer_set[1].content
'๋๋ฒ์งธ 1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค'
๋ค์๊ณผ ๊ฐ์ด Answer๋ ์ ๋ ฅ์ด ๊ฐ๋ฅ
>>> a = Answer(question_id=1, content="1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค", create_date=datetime.now())
>>> a
<Answer (transient 2955131376432)>
>>> db.session.add(a)
>>> db.session.commit()
>>> a
<Answer 1>
>>> a.question_id
1
>>> a.question
<Question 1>
>>> a.question.content
'๋ด์ฉ์
๋๋ค'
>>> a.question.subject
'์ ๋ชฉ์
๋๋ค'
>>> q = a.question
>>> q.answer_set
[<Answer 1>]
>>> a = Answer(question_id=1, content="๋๋ฒ์งธ 1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค", create_date=datetime.now())
>>> a
<Answer (transient 2955131818416)>
>>> db.session.add(a)
>>> db.session.commit()
>>> q.answer_set
[<Answer 1>, <Answer 2>]
>>> q.answer_set[1].content
'๋๋ฒ์งธ 1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค'


๋ค์๊ณผ ๊ฐ์ด ํ์ธ ํ ์ ์๋ค.
https://github.com/DINOQOS/fisa-flask
GitHub - DINOQOS/fisa-flask
Contribute to DINOQOS/fisa-flask development by creating an account on GitHub.
github.com
ํ๋ฉด์ ํ์ํ๋ ๋ช
๋ น์ด ์ ๋ฆฌ
# pip๋ฅผ ํตํด ์ต์ํ์ ๊ฐ์ํ๊ฒฝ์ ์์ฑํ๋ ๋ช
๋ น์ด
$ python -m venv myproject
$ cd myproject\Scripts
C:\itstudy\06_flask\flak01\myproject\Scripts> activate
$ (myproject) C:\itstudy\06_flask\flak01\myproject\Scripts>
# ํ์ด์ฌ ๋ด์ฅ ๋ชจ๋๋ก ์น ์๋ฒ ์คํํ๊ธฐ
$ python -m http.server 8080
$ deactivate
$ python -m pip install --upgrade pip
$ pip install flask
### test.py
from flask import Flask
# app.py์ธ ๊ณณ์ ์
๊ตฌ๋ก ์ฐพ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์คํํฉ๋๋ค
# ๋๋ FLASK_APP์ด๋ผ๋ ํ๊ฒฝ๋ณ์์ ์ด๋ฆ์ ํ์ผ๋ช
์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค
# set FLASK_APP=test
# wsgi.py์ ์ง์ ํค=๋ฐธ๋ฅ๋ก ์ฌ๋ฌ ํ๊ฒฝ๋ณ์๋ค์ ๊ธฐ์
ํฉ๋๋ค.
app = Flask(__name__)
@app.route("/")
def hello():
return f'Hello {__name__}'
# localhost:5000/bye ๋ก ์ ์ํ๋ฉด bye ๋ง ์ถ๋ ฅ๋๋๋ก ์ปจํธ๋กค๋ฌ๋ฅผ ๋ง๋ค์ด์ฃผ์ธ์
@echo off
set FLASK_APP=test
set FLASK_DEBUG=true
C:\ITStudy\09_flask\fisa-flask\myproject\Scripts\activate.bat
## ์ ํ๋ฆฌ์ผ์ด์
ํฉํ ๋ฆฌ
$ mkdir test
$ move test.py test/__init__.py # ๋งฅ์ด๋ ๋ฆฌ๋
์ค์์๋ move ๋์ mv ๋ช
๋ น์ด ์ฌ์ฉ
$ flask run
from flask import Flask
def create_app():
app = Flask(__name__)
# URL๊ณผ FLASK์ฝ๋๋ฅผ ๋งคํํ๋ Flask ๋ฐ์ฝ๋ ์ดํฐ
# @app.route์ฒ๋ผ ์ ๋
ธํ
์ด์
์ผ๋ก URL์ ๋งคํํ๋ ํจ์๋ฅผ ๋ผ์ฐํ
ํจ์๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
@app.route('/')
def hello():
return f'Hello, {__name__}'
@app.route('/yeonji')
def hello_yeonji():
return f'Hello, yeonji'
return app
mkdir views
cd views
# projects/myproject/test/views/main_views.py
from flask import Blueprint
bp = Blueprint('main', __name__, url_prefix='/')
@bp.route('/')
def hello():
return f'Hello, {__name__}'
## __init__.py์ ์ถ๊ฐ
from .views import main_views # views ํด๋ ๋ฐ์ main_views.py ์ํฌํธ
test.register_blueprint(main_views.bp)
## views/main_views.py
from flask import Blueprint
bp = Blueprint('main', __name__, url_prefix="/main")
@bp.route("/")
def hello():
return f'main์์ ์์ฑํ Hello {__name__}'
## __init__.py
from flask import Flask
# app.py์ธ ๊ณณ์ ์
๊ตฌ๋ก ์ฐพ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์คํํฉ๋๋ค
# ๋๋ FLASK_APP์ด๋ผ๋ ํ๊ฒฝ๋ณ์์ ์ด๋ฆ์ ํ์ผ๋ช
์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค
# set FLASK_APP=test
# wsgi.py์ ์ง์ ํค=๋ฐธ๋ฅ๋ก ์ฌ๋ฌ ํ๊ฒฝ๋ณ์๋ค์ ๊ธฐ์
ํฉ๋๋ค.
def create_app(): # ์ดํ๋ฆฌ์ผ์ด์
ํฉํ ๋ฆฌ - ํ๋ผ์คํฌ ์๋ฒ๊ฐ ์คํ๋ ๋ ๊ฐ์ฅ ์ต์ด๋ก ์คํ๋๋ ์์ฑ์
test = Flask(__name__)
from .views import main_views # views ํด๋ ๋ฐ์ main_views.py ์ํฌํธ
test.register_blueprint(main_views.bp)
return test
## test/views/main_views.py
from flask import Blueprint
bp = Blueprint('main', __name__, url_prefix="/")
@bp.route("/")
def hello():
return f'main์์ ์์ฑํ Hello {__name__}'
@bp.route("/bye")
def bye():
return f'BYE'
https://github.com/YeonjiKim0316/fisa-ai-flask
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
# app.py์ธ ๊ณณ์ ์
๊ตฌ๋ก ์ฐพ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์คํํฉ๋๋ค
# ๋๋ FLASK_APP์ด๋ผ๋ ํ๊ฒฝ๋ณ์์ ์ด๋ฆ์ ํ์ผ๋ช
์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค
# set FLASK_APP=test
# wsgi.py์ ์ง์ ํค=๋ฐธ๋ฅ๋ก ์ฌ๋ฌ ํ๊ฒฝ๋ณ์๋ค์ ๊ธฐ์
ํฉ๋๋ค.
import config
db = SQLAlchemy()
migrate = Migrate()
## test/__init__.py
def create_app(): # ์ดํ๋ฆฌ์ผ์ด์
ํฉํ ๋ฆฌ - ํ๋ผ์คํฌ ์๋ฒ๊ฐ ์คํ๋ ๋ ๊ฐ์ฅ ์ต์ด๋ก ์คํ๋๋ ์์ฑ์
test = Flask(__name__)
# ORM
test.config.from_object(config)
db.init_app(test)
migrate.init_app(test, db)
# ๋ธ๋ฃจํ๋ฆฐํธ
from .views import main_views # views ํด๋ ๋ฐ์ main_views.py ์ํฌํธ
test.register_blueprint(main_views.bp)
return test
#
from test import db
class Question(db.Model):
id = db.Column(db.Integer, primary_key=True)
subject = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text(), nullable=False)
create_date = db.Column(db.DateTime(), nullable=False)
class Answer(db.Model):
id = db.Column(db.Integer, primary_key=True)
question_id = db.Column(db.Integer, db.ForeignKey('question.id', ondelete='CASCADE'))
question = db.relationship('Question', backref=db.backref('answer_set'))
content = db.Column(db.Text(), nullable=False)
create_date = db.Column(db.DateTime(), nullable=False)
## flask shell
>>> from test.models import Question
>>> from datetime import datetime
>>> q = Question(subject="์ ๋ชฉ์
๋๋ค", content="๋ด์ฉ์
๋๋ค", create_date=datetime.now())
>>> q
<Question (transient 2955131385264)>
>>> from test import db
>>> db.session.add(q)
>>> db.session.commit()
>>> q
<Question 1>
>>> q.id
1
>>> q.content
'๋ด์ฉ์
๋๋ค'
>>> q.subject
'์ ๋ชฉ์
๋๋ค'
>>> Question.query.all()
[<Question 1>]
>>> Question.query.filter(Question.id==1).all()
[<Question 1>]
>>> q
<Question (transient 2955131821776)>
>>> db.session.add(q)
>>> db.session.commit()
>>> Question.query.all()
[<Question 1>, <Question 2>]
>>> q = Question(subject="์ ๋ชฉ์
๋๋ค", content="๋ด์ฉ์
๋๋ค", create_date=datetime.now())
>>> q1 = Question(subject="๋ ์จ๊ฐ ์ถ์์
๋๋ค", content="๋ด์ฉ์
๋๋ค", create_date=datetime.now())
>>> q
<Question (transient 2955131387856)>
>>> q1
<Question (transient 2955131822592)>
>>> db.session.add(q)
>>> db.session.add(q1)
>>> db.session.commit()
>>> Question.query.filter(Question.id==2).all()
[<Question 2>]
>>> Question.query.filter(Question.id==2).all()
[<Question 2>]
>>> q = Question.query.filter(Question.id==2).all()
>>> q.subject
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'list' object has no attribute 'subject'
>>> q.content
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'list' object has no attribute 'content'
>>> q = Question.query.filter(Question.id==2).get()
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: Query.get() missing 1 required positional argument: 'ident'
>>> q = Question.query.get(2)
>>> q
<Question 2>
>>> q.subject
'์ ๋ชฉ์
๋๋ค2'
>>> q = Question.query.filter(Question.subject.like("%๋ ์จ%")).get()
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: Query.get() missing 1 required positional argument: 'ident'
>>> q = Question.query.filter(Question.subject.like("%๋ ์จ%")).all()
>>> q
[<Question 4>]
>>> q[0]
<Question 4>
>>> q[0].subject
'๋ ์จ๊ฐ ์ถ์์
๋๋ค'
>>> q[0].subject = "๋ ์จ๊ฐ ๋งค์ฐ ์ถฅ์ต๋๋ค"
>>> q[0].subject
'๋ ์จ๊ฐ ๋งค์ฐ ์ถฅ์ต๋๋ค'
>>> db.session.commit()
>>> q
[<Question 4>]
>>> db.session.delete(q)
Traceback (most recent call last):
File "C:\ITStudy\09_flask\fisa-flask\myproject\lib\site-packages\sqlalchemy\orm\session.py", line 3478, in delete
state = attributes.instance_state(instance)
AttributeError: 'list' object has no attribute '_sa_instance_state'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\ITStudy\09_flask\fisa-flask\myproject\lib\site-packages\sqlalchemy\orm\scoping.py", line 672, in delete
return self._proxied.delete(instance)
File "C:\ITStudy\09_flask\fisa-flask\myproject\lib\site-packages\sqlalchemy\orm\session.py", line 3480, in delete
raise exc.UnmappedInstanceError(instance) from err
sqlalchemy.orm.exc.UnmappedInstanceError: Class 'builtins.list' is not mapped
>>> db.session.delete(q[0])
>>> db.session.commit()
- ์ฌ๋ฌ๋ถ์ ์ด๋ฆ์ question ํ
์ด๋ธ์ content ์์ฑ์ ๋ฃ์ด์ 1๊ฐ ๊ธ์ ์์ฑํ์ธ์
- filter๋ฅผ ์ฌ์ฉํด์ ๊ทธ ๊ธ์ ๊ฐ์ ธ์๋ณด์ธ์
- ๊ธ์ content๋ฅผ '์ ์งฑ๊ตฌ'๋ก ๋ณ๊ฒฝํด๋ณด์ธ์
- ๊ทธ ๊ธ์ ์ญ์ ํด์ฃผ์ธ์
>>> db.session.delete(q[0])
>>> db.session.commit()
>>> a = Answer(question_id=1, content="1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค", create_date=datetime.now())
>>> a
<Answer (transient 2955131376432)>
>>> db.session.add(a)
>>> db.session.commit()
>>> a
<Answer 1>
>>> a.question_id
1
>>> a.question
<Question 1>
>>> a.question.content
'๋ด์ฉ์
๋๋ค'
>>> a.question.subject
'์ ๋ชฉ์
๋๋ค'
>>> q = a.question
>>> db.session.delete(q[0])
>>> db.session.commit()
>>> a = Answer(question_id=1, content="1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค", create_date=datetime.now())
>>> a
<Answer (transient 2955131376432)>
>>> db.session.add(a)
>>> db.session.commit()
>>> a
<Answer 1>
>>> a.question_id
1
>>> a.question
<Question 1>
>>> a.question.content
'๋ด์ฉ์
๋๋ค'
>>> a.question.subject
'์ ๋ชฉ์
๋๋ค'
>>> q = a.question
>>> q.answer_set
[<Answer 1>]
>>> a = Answer(question_id=1, content="๋๋ฒ์งธ 1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค", create_date=datetime.now())
>>> a
<Answer (transient 2955131818416)>
>>> db.session.add(a)
>>> db.session.commit()
>>> q.answer_set
[<Answer 1>, <Answer 2>]
>>> q.answer_set[1].content
'๋๋ฒ์งธ 1๋ฒ ๊ธ์ ๋ํ ๋ต๋ณ์
๋๋ค'
{# <% %> = {% %}
<%= %> = {{ }}
<%-- --%> = {# ... #}
<jsp include: > = {% include 'header.html' %} #}
{% for item in list %}
<p>์์: {{ loop.index }} </p>
<p>{{ item }}</p>
{% endfor %}
https://docs.sqlalchemy.org/en/13/orm/query.html
https://sqlitebrowser.org/dl/
## templates/post_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% for item in question_list %}
<p>์์: {{ loop.index }} </p>
<p>์ ๋ชฉ: {{ item.subject }}</p>
<p>๋ด์ฉ: {{ item.content }}</p>
<p>๊ฒ์์ผ: {{ item.create_date }}</p>
{% endfor %}
</body>
</html>
{% if ์กฐ๊ฑด๋ฌธ1 %}
<p>์กฐ๊ฑด๋ฌธ1์ ํด๋นํ๋ฉด ์คํ</p>
{% elif ์กฐ๊ฑด๋ฌธ2 %}
<p>์กฐ๊ฑด๋ฌธ2์ ํด๋นํ๋ฉด ์คํ</p>
{% else %}
<p>์กฐ๊ฑด๋ฌธ1, 2 ๋ชจ๋ ํด๋นํ์ง ์์ผ๋ฉด ์คํ</p>
{% endif %}
## ์์ธ ๊ฒ์ํ ๊ธ ์กฐํ๋ฅผ ์ํ MVC
# templates/question_detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=\, initial-scale=1.0">
<title>Document</title>
</head>
<body>
์ ๋ชฉ
๋ด์ฉ
๊ฒ์์ผ
</body>
</html>
# views/board_views.py
from flask import Blueprint, render_template
from ..models import Question, Answer
# ์ฐ๋ฆฌ๊ฐ ๋ถ๋ฅผ ์ด๋ฆ, flask ํ๋ ์์ํฌ๊ฐ ์ฐพ์ ์ด๋ฆ, ๋ผ์ฐํ
์ฃผ์
board = Blueprint('board', __name__, url_prefix="/board")
@board.route("/post")
def post_list():
question_list = Question.query.all()
return render_template("question_list.html", question_list=question_list)
# board/detail/1 2 3 4 -> question_detail.html๋ก ๊ฐ ๊ธ์ ์ค์ ์ธ๋ถ๋ด์ฉ์ ์ ๋ฌํ๊ณ ์ถ์ด์
@board.route("/detail/<int:question_id>") #
def post_detail(question_id):
return f"{question_id}"
## board_views.py
from flask import Blueprint, render_template
from ..models import Question, Answer
# ์ฐ๋ฆฌ๊ฐ ๋ถ๋ฅผ ์ด๋ฆ, flask ํ๋ ์์ํฌ๊ฐ ์ฐพ์ ์ด๋ฆ, ๋ผ์ฐํ
์ฃผ์
board = Blueprint('board', __name__, url_prefix="/board")
@board.route("/post")
def post_list():
question_list = Question.query.all()
return render_template("question_list.html", question_list=question_list)
# board/detail/1 2 3 4 -> question_detail.html๋ก ๊ฐ ๊ธ์ ์ค์ ์ธ๋ถ๋ด์ฉ์ ์ ๋ฌํ๊ณ ์ถ์ด์
@board.route("/detail/<int:question_id>") # question_id ๋ณ์๋ก ๋ฐ์ ๊ฐ์
def post_detail(question_id): # ํจ์์ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ
# question = Question.query.get(question_id) # ๋ชจ๋ธ์์ ํน์ ๋ฒํธ(id)๋ฅผ ํตํด ๊ฐ์ ์กฐํ
question = Question.query.get_or_404(question_id)
return render_template("question_detail.html", ques = question)
# views/main_views.py
from flask import Blueprint
from ..models import Question
# ์ฐ๋ฆฌ๊ฐ ๋ถ๋ฅผ ์ด๋ฆ, flask ํ๋ ์์ํฌ๊ฐ ์ฐพ์ ์ด๋ฆ, ๋ผ์ฐํ
์ฃผ์
bp = Blueprint('main', __name__, url_prefix="/")
# ์ฒซ๋ฒ์งธ blueprint๋ถํฐ ์ฐพ๊ธฐ ๋๋ฌธ์ board๋ฅผ ์ธ ์ ์๊ฒ ๋ฉ๋๋ค
# @bp.route("/", defaults={"var":'', "var2":""}) # ์ฌ๋ฌ๊ฐ์ route ์ด๋
ธํ
์ด์
์ ํ๋์ ๋ฉ์๋์ ์น์ด์ ์ธ ์๋ ์๋ค
# @bp.route("/<var>/<var2>") #๋๋ถ๋ถ uri๋ str๋ก ๋ฐ๊ธฐ ๋๋ฌธ์ str์ ์๋ต # localhost:5000/yeonji -> hello yeonji๊ฐ ์ถ๋ ฅ๋๋๋ก
@bp.route("/")
def hello(var, var2):
return f'main์์ ์์ฑํ Hello {var} {var2}'
@bp.route("/bye")
def bye():
return f'BYE'
## templates/post_detail.html
{% for ans in ques.answer_set %}
<hr>
{{ ans.id }} <br>
{{ ans.content }} <br>
{{ ans.create_date }} <br>
{% endfor %}
## templates/post_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% for item in question_list %}
<p>์์: {{ loop.index0 }} </p>
<p>์ ๋ชฉ: <a href="/board/detail/{{ item.id }}"> {{ item.subject }}</a></p>
<p>๊ฒ์์ผ: {{ item.create_date }}</p>
{% endfor %}
{% if False %}
<p>์กฐ๊ฑด๋ฌธ1์ ํด๋นํ๋ฉด ์คํ</p>
{% elif True %}
<p>์กฐ๊ฑด๋ฌธ2์ ํด๋นํ๋ฉด ์คํ</p>
{% else %}
<p>์กฐ๊ฑด๋ฌธ1, 2 ๋ชจ๋ ํด๋นํ์ง ์์ผ๋ฉด ์คํ</p>
{% endif %}
</body>
</html>
https://github.com/YeonjiKim0316/fisa-flask
pip freeze > requirements.txt
git add .
git commit -m "flask day 1"
git push origin main
// woorifisa ์๋ค๊ฐ ๊ฐ์ ์์
์ ํด ๋ณด์ญ์์ค'Tech Stack > Flask' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| flask - Pagination (0) | 2024.02.15 |
|---|---|
| Flask 2 - MVC(MTV)ํจํด์ผ๋ก ์ง๋ฌธ๋ต๋ณ ๊ฒ์ํ ๋ง๋ค๊ธฐ (1) | 2024.02.14 |