웹사이트 검색

Flask 청사진 및 Flask-SQLAlchemy를 사용하여 대규모 Flask 애플리케이션을 구성하는 방법


저자는 Write for DOnations 프로그램을 선택했습니다.

소개

Flask-SQLAlchemy는 Flask와 함께 SQLAlchemy를 더 쉽게 사용할 수 있게 해주는 Flask 확장으로, Flask 응용 프로그램에서 데이터베이스와 상호 작용하는 도구 및 방법을 제공합니다.

Flask는 하나의 Python 파일로 작은 웹 애플리케이션을 빠르게 빌드할 수 있는 방법을 제공합니다. 그러나 작은 응용 프로그램은 여러 데이터베이스 테이블, 수백 개의 경로 및 복잡한 기능이 있는 큰 응용 프로그램으로 성장할 수 있습니다. 하나의 파일에 큰 응용 프로그램의 코드를 작성하면 금세 복잡해지고 관리하기 어려워집니다. Flask를 사용하면 응용 프로그램의 각 주요 부분을 더 잘 구성된 응용 프로그램을 위한 특정 디렉터리 및 파일로 분할하여 응용 프로그램의 코드 기반을 구성할 수 있습니다.

예를 들어, 소셜 미디어 애플리케이션에서 users라는 디렉터리 안에 있는 routes.py라는 파일에 사용자에 대한 경로가 있을 수 있으며 그런 다음 데이터베이스를 수집할 수 있습니다. models 디렉토리 안에 있는 users.py라는 모듈 안에 있는 사용자를 위한 모델. 그런 다음 대규모 소셜 미디어 애플리케이션의 게시물, 팔로워, 해시태그, 질문, 답변, 광고, 시장, 결제 및 기타 기능에 대해 동일한 작업을 수행할 수 있습니다. 일부 비즈니스 로직을 결제 코드로 편집하려는 경우 mysocialapp/models/payment.py에 있는 파일에서 결제용 데이터베이스 코드를 변경한 다음 위치한 파일에서 비즈니스 로직을 변경할 수 있습니다. mysocialapp/payments/routes.py에서. 애플리케이션의 각 부분은 서로 다른 파일 및 디렉토리에 코드를 격리하여 애플리케이션을 관리하기 쉬운 구성 요소로 효과적으로 분할합니다. 이 구조는 또한 새 개발자가 응용 프로그램에 익숙해지도록 도와주므로 문제를 해결하거나 새 기능을 추가할 위치를 알 수 있습니다.

Flask는 응용 프로그램 구성 요소를 만들기 위한 청사진이라는 기능을 제공합니다. 이전 예에서 청사진을 사용하여 각 기능에 대해 사용자 청사진, 게시물 청사진, 팔로워 청사진 등과 같은 다양한 청사진으로 대규모 소셜 미디어 애플리케이션을 구성할 수 있습니다.

이 자습서에서는 Flask 청사진을 사용하여 홈 페이지 및 기타 기본 경로를 포함하는 기본 청사진, 블로그 게시물 관리를 위한 게시물 청사진, 질문 및 답변을 위한 질문 청사진의 세 가지 구성 요소로 웹 애플리케이션을 구성합니다.

전제 조건

  • 로컬 Python 3 프로그래밍 환경은 Python 3 시리즈용 로컬 프로그래밍 환경을 설치 및 설정하는 방법의 배포용 자습서를 따라 설정할 수 있습니다. 이 자습서에서는 프로젝트 디렉터리를 flask_app라고 합니다.\n
  • 경로, 보기 기능 및 템플릿과 같은 기본 Flask 개념에 대한 이해 Flask에 익숙하지 않은 경우 Flask 애플리케이션에서 템플릿을 사용하는 방법을 확인하세요.\n
  • 기본 HTML 개념에 대한 이해. 배경 지식은 HTML 자습서 시리즈를 사용하여 웹 사이트를 구축하는 방법을 검토할 수 있습니다.\n
  • 데이터베이스 설정, 데이터베이스 모델 생성 및 데이터베이스에 데이터 삽입과 같은 기본 Flask-SQLAlchemy 개념에 대한 이해. 배경 지식은 Flask-SQLAlchemy를 사용하여 Flask 애플리케이션에서 데이터베이스와 상호 작용하는 방법을 참조하세요.\n

대상 애플리케이션 구조

자습서가 끝나면 다음 구조로 Flask 애플리케이션을 빌드하게 됩니다.

.
└── flask_app
    ├── app
    │   ├── extensions.py
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── models
    │   │   ├── post.py
    │   │   └── question.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── questions
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       ├── posts
    │       │   ├── categories.html
    │       │   └── index.html
    │       └── questions
    │           └── index.html
    ├── app.db
    └── config.py

flask_app 디렉토리 안에는 Flask 애플리케이션을 위한 app.db 데이터베이스 파일과 config.py 구성 파일이 있습니다. 기본 Flask 애플리케이션은 app 디렉토리에 있으며, 여기에는 가져오기가 제대로 작동하도록 패키지로 만드는 __init__.py 특수 파일이 있으며 다음을 포함합니다. Flask 애플리케이션 인스턴스를 생성하기 위한 함수.

app 디렉토리에는 애플리케이션에서 사용할 Flask 확장을 관리하기 위한 extensions.py 파일이 포함됩니다(이 자습서에서 Flask-SQLAlchemy는 플라스크 확장). 다음 디렉토리도 있습니다.

  • main: 홈 페이지와 같은 기본 경로의 기본 청사진입니다.
  • posts: 블로그 게시물 관리를 위한 게시물 청사진
  • 질문: 질문과 답변을 관리하기 위한 질문 청사진
  • models: Flask-SQLAlchemy 모델을 포함할 디렉터리입니다.
  • templates: 기본 청사진에 대한 파일과 각 청사진에 대한 디렉토리를 포함할 템플릿 디렉토리입니다.

1단계 - Flask 및 Flask-SQLAlchemy 설치

이 단계에서는 애플리케이션에 필요한 패키지를 설치합니다.

flask_app 디렉터리에서 가상 환경을 활성화합니다.

  1. source my_env/bin/activate

가상 환경이 활성화된 상태에서 pip를 사용하여 Flask 및 Flask-SQLAlchemy를 설치합니다.

  1. pip install Flask Flask-SQLAlchemy

설치가 완료되면 출력에 다음과 유사한 줄이 인쇄됩니다.

Output
Successfully installed Flask-2.1.2 Flask-SQLAlchemy-2.5.1 Jinja2-3.1.2 MarkupSafe-2.1.1 SQLAlchemy-1.4.39 Werkzeug-2.1.2 click-8.1.3 greenlet-1.1.2 itsdangerous-2.1.2

필요한 Python 패키지가 설치되면 다음 단계에서 Flask 애플리케이션의 설정을 관리하기 위한 구성 파일을 설정합니다.

2단계 - 구성 파일 생성

이 단계에서는 Flask 애플리케이션에 대한 구성 파일을 생성하여 애플리케이션 설정을 애플리케이션의 나머지 부분과 분리하고 설정 변경을 더 쉽게 만듭니다. 구성 파일은 SQLAlchemy 데이터베이스 URI 등과 같은 항목을 구성합니다.

flask_app 디렉터리에서 config.py라는 새 파일을 엽니다. 이 파일은 Flask 애플리케이션의 구성을 보유합니다.

  1. nano config.py

다음 코드를 추가합니다.

import os

basedir = os.path.abspath(os.path.dirname(__file__))


class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI')\
        or 'sqlite:///' + os.path.join(basedir, 'app.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

파일을 저장하고 닫습니다.

파일 시스템에 액세스하기 위해 os 모듈을 가져옵니다. 데이터베이스 파일의 경로를 올바르게 설정하려면 os를 사용하여 os.path.abspath(os.path.dirname(__file__))로 기본 디렉토리를 설정합니다.

Config라는 클래스를 사용하고 클래스 변수를 사용하여 구성 값을 설정합니다. 여기에서 세 가지 구성을 설정합니다.

  • SECRET_KEY: Flask에서 비밀 키로 사용하는 긴 임의 문자열 또는 한 요청에서 다른 요청으로 정보를 기억하는 세션을 보호하는 데 사용되는 키입니다. 사용자는 세션에 저장된 정보에 액세스할 수 있지만 비밀 키가 없으면 수정할 수 없으므로 누구도 비밀 키에 액세스하도록 허용해서는 안 됩니다. get() 메서드를 사용하여 os.environ 개체를 참조하십시오. (이 자습서를 따르기 위해 비밀 키를 설정할 필요는 없지만 비밀 키를 설정하는 방법에 대한 지침은 이 목록 끝에 있는 참고 사항을 검토할 수 있습니다.)\n
  • SQLALCHEMY_DATABASE_URI: 데이터베이스 URI는 SQLAlchemy를 사용하여 연결을 설정하려는 데이터베이스를 지정합니다. 이 경우 DATABASE_URI 환경 변수에서 가져오거나 기본값을 설정합니다. 여기서 기본 URI 값은 sqlite:///path/to/app.db 형식을 따릅니다. os.path.join() 함수를 사용하여 구성하고 basedir 변수에 저장한 기본 디렉토리와 app.db 파일 이름. 이를 통해 DATABASE_URI 환경 변수를 설정하지 않고 Flask 애플리케이션을 생성하면 기본적으로 flask_app 디렉토리의 app.db 데이터베이스 파일에 연결됩니다. 파일은 데이터베이스 테이블을 생성할 때 생성됩니다. 다른 SQL 엔진에 대한 데이터베이스 URI를 설정하려면 Flask-SQLAlchemy를 사용하여 Flask 애플리케이션에서 데이터베이스와 상호 작용하는 방법의 2단계를 참조하세요.\n
  • SQLALCHEMY_TRACK_MODIFICATIONS: 개체의 수정 추적을 활성화 또는 비활성화하는 구성입니다. 추적을 비활성화하고 메모리를 적게 사용하려면 False로 설정합니다. 자세한 내용은 Flask-SQLAlchemy 설명서의 구성 페이지를 참조하세요.\n

참고: 비밀 키가 필요한 기능을 사용하지 않기 때문에 이 자습서에서는 비밀 키를 설정하지 않습니다. 그러나 비밀 키를 설정해야 하는 경우 다음과 같이 설정할 수 있습니다(Windows의 경우 export 대신 set 사용).

  1. export SECRET_KEY="your secret key"

마찬가지로 다음과 같이 데이터베이스 URI를 설정할 수 있습니다(Windows에서는 set 사용).

  1. export DATABASE_URI="postgresql://username:password@host:port/database_name"

이제 애플리케이션에 대한 구성 파일을 설정했습니다. 다음으로 Flask 애플리케이션 인스턴스를 설정하고 Flask 애플리케이션의 다양한 구성 요소를 나타내는 몇 가지 블루프린트를 생성합니다.

3단계 — Flask 애플리케이션 팩토리 생성

이 단계에서는 Flask 애플리케이션 인스턴스를 설정하는 Python 함수인 Flask 애플리케이션 팩토리를 만듭니다.

튜토리얼의 이 시점에서 flask_app 디렉토리 구조는 다음과 같습니다(가상 환경의 디렉토리 제외).

.
├── flask_app
   └── config.py

애플리케이션의 핵심 코드는 Python 패키지가 될 프로젝트 디렉토리 안에 있습니다. 이 자습서에서는 app라고 부르지만 프로젝트 이름이나 src, core, 또는 이와 유사한 것.

애플리케이션의 핵심 코드가 포함된 폴더를 Python 패키지로 만들어 가져오기가 코드 기반 전체에서 올바르게 작동하고 유지 관리성을 높일 수 있습니다.

app 프로젝트 디렉토리를 Python 패키지로 만들려면 디렉토리를 Python 패키지로 표시하는 특별한 __init__.py 파일을 내부에 생성합니다. 이 __init__.py 파일은 모든 Flask를 연결하는 Flask 애플리케이션 인스턴스를 설정하고 생성하는 데 사용할 함수인 Flask 팩터리 함수에 대한 코드를 보유합니다. 함께 청사진. 공장 기능을 모든 Flask 구성 요소(청사진)가 하나의 애플리케이션으로 결합되고 다양한 구성으로 다양한 목적을 위해 다양한 Flask 애플리케이션 인스턴스를 생성하는 데 사용할 수 있는 중앙 기능으로 생각하세요. 예를 들어 팩토리 기능을 사용하여 테스트를 위한 적절한 구성으로 테스트를 위한 Flask 애플리케이션 인스턴스를 생성할 수 있습니다.

flask_app 디렉터리 내부에 다음과 같은 새 app 디렉터리를 만듭니다.

  1. mkdir app

그런 다음 app 디렉터리 내에서 새 __init__.py 파일을 엽니다.

  1. nano app/__init__.py

다음 코드를 추가합니다.

from flask import Flask

from config import Config

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here

    # Register blueprints here

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

파일을 저장하고 닫습니다.

이 파일에서는 flask 패키지에서 Flask 클래스를 가져옵니다. 그런 다음 이전 단계에서 flask_app 디렉토리에 생성한 config.py 파일에서 Config 구성 클래스를 가져옵니다.

create_app() 함수는 Flask 애플리케이션 팩토리 함수입니다. 친숙한 app = Flask(__name__) 라인을 사용하여 Flask() 클래스에서 app라는 애플리케이션 인스턴스를 생성합니다. app.config.from_object() 메서드를 사용하여 개체에서 구성 값을 가져오고 config_class 매개변수의 값을 전달하여 애플리케이션을 구성합니다. >Config 클래스를 기본값으로 사용합니다. # Initialize Flask extensions here 주석 아래에서 Flask 확장을 초기화하고 # 여기에 청사진 등록 주석 아래에 애플리케이션 청사진을 등록합니다.

애플리케이션 팩토리 내부에 경로를 등록하는 방법을 보여주기 위해 팩토리 함수 내부의 app.route() 데코레이터를 사용하여 테스트 경로를 생성합니다. 이 경우 test_page() 뷰 함수는 제목 Flask 애플리케이션 팩토리 패턴 테스트를 반환합니다.

마지막으로 create_app() 팩토리 함수는 return app 줄로 구성한 애플리케이션 인스턴스를 반환합니다.

Flask는 app 패키지에서 create_app() 팩토리 함수를 자동으로 감지하고 이를 사용하여 애플리케이션 인스턴스를 생성합니다. 그러나 먼저 개발 모드에서 Flask 애플리케이션을 실행하는 데 필요한 환경 변수를 설정해야 합니다.

가상 환경이 활성화된 flask_app 디렉터리에 있는 동안 핵심 애플리케이션의 디렉터리 이름 app을 값으로 FLASK_APP 환경 변수. 그런 다음 FLASK_ENV 환경 변수를 development로 설정하여 개발 모드에서 애플리케이션을 실행하고 디버거에 액세스할 수 있습니다. Flask 디버거에 대한 자세한 내용은 Flask 애플리케이션에서 오류를 처리하는 방법을 참조하세요.

먼저 app 패키지를 Flask가 create_app() 팩터리 함수를 찾아야 하는 위치로 설정합니다.

  1. export FLASK_APP=app

app.py라는 단일 Python 파일에서 Flask 애플리케이션을 빌드하는 데 익숙할 수 있습니다. 이 경우 동일한 명령을 사용하여 Flask에 애플리케이션을 찾을 위치를 알려줍니다. 차이점은 이전 명령의 app__init__.py 파일이 있는 프로젝트의 핵심 디렉터리에 대한 것이라는 것입니다.

개발 모드에서 애플리케이션을 실행하도록 FLASK_ENV 환경 변수를 설정합니다.

  1. export FLASK_ENV=development

그런 다음 애플리케이션을 실행합니다.

  1. flask run

개발 서버가 실행 중인 상태에서 브라우저를 사용하여 다음 URL을 방문하십시오.

http://127.0.0.1:5000/test/

Testing the Flask Application Factory Pattern 제목과 함께 사이트가 로드됩니다.

이제 Flask 애플리케이션 팩터리 기능을 만들었습니다. 다음으로 Flask 블루프린트를 생성하고 이 팩토리 함수에 등록합니다.

4단계 - Flask Blueprint 생성

이 단계에서는 Flask 애플리케이션의 주요 구성 요소를 관리할 기본 경로에 대한 청사진을 만든 다음 공장 기능에 청사진을 등록합니다. 블로그 게시물, 질문 및 답변에 대해 각각 다른 청사진을 생성합니다. 각 청사진에 몇 개의 경로를 추가하고 각 청사진에 대한 templates 디렉터리가 있는 각 경로에 대한 템플릿을 렌더링합니다.

튜토리얼의 이 시점에서 flask_app 디렉토리 구조는 다음과 같습니다(가상 환경의 디렉토리 제외).

.
├── flask_app
    ├── app
    │   └── __init__.py
    └── config.py

메인 블루프린트 생성 및 템플릿 렌더링

이제 애플리케이션의 기본 청사진을 생성하고 해당 템플릿을 렌더링합니다.

이전 단계에서 시작한 개발 서버를 실행 중인 상태로 두고 새 터미널을 엽니다.

새 터미널에서 flask_app 디렉터리로 이동합니다. 그런 다음 app 디렉토리 안에 기본 청사진을 위한 main이라는 디렉토리를 만듭니다.

  1. mkdir app/main

다음으로, 새 main 디렉터리 내에서 새 __init__.py 기본 파일을 엽니다.

  1. nano app/main/__init__.py

여기에서 기본 청사진을 만들 수 있습니다. 이 파일에 다음 코드를 추가합니다.

from flask import Blueprint

bp = Blueprint('main', __name__)

파일을 저장하고 닫습니다.

여기서는 flask 패키지에서 Blueprint 클래스를 가져옵니다. 그런 다음 이 클래스를 사용하여 청사진 개체 bp를 만들고 이름(이 경우 main)과 특수 __name__이라는 두 개의 인수를 전달합니다. 현재 Python 모듈의 이름을 보유하는 변수.

이제 이전 단계에서 작성한 create_app() 팩터리 함수를 사용하여 만든 Flask 애플리케이션에 나중에 연결할 수 있는 경로와 함수가 있는 청사진 개체가 있습니다.

다음으로, main 청사진 디렉토리 안에 routes.py 파일을 생성합니다. 이 파일은 기본 청사진의 경로를 포함합니다. 기본 청사진 디렉터리 내에서 새 routes.py 파일을 엽니다.

  1. nano app/main/routes.py

bp 개체를 사용하여 경로를 만듭니다. 새 파일 내에 다음 경로를 추가합니다.

from app.main import bp


@bp.route('/')
def index():
    return 'This is The Main Blueprint'

파일을 저장하고 닫습니다.

여기에서 app.main을 통해 액세스하는 기본 청사진에서 bp 청사진 개체를 가져옵니다. 가져오기 줄에서 app은 프로젝트의 패키지이고 main은 기본 청사진 패키지이며 bp는 기본 청사진에서 선언한 개체입니다. __init__.py 파일.

bp 개체를 사용하여 bp.route()/ 경로와 index() 뷰 함수를 만듭니다. 데코레이터, 친숙한 app.route() 데코레이터와 유사합니다.

Flask가 이러한 경로를 사용하고 청사진에서 직접 가져올 수 있도록 하려면 청사진의 __init__.py 파일에서 이 routes.py 파일을 가져와야 합니다. 편집을 위해 엽니다.

  1. nano app/main/__init__.py

파일 끝에 강조 표시된 가져오기 줄을 추가합니다.

from flask import Blueprint

bp = Blueprint('main', __name__)

from app.main import routes

파일을 저장하고 닫습니다.

이 추가로 청사진을 등록하면 해당 경로도 등록됩니다.

청사진을 만들고 경로를 추가했으므로 이제 Flask 애플리케이션의 일부로 처리될 수 있도록 이 새 청사진에 대해 Flask에 알려야 합니다. 이를 위해 Flask 애플리케이션 팩토리 기능 내에 청사진을 등록합니다.

app/__init__.py 파일을 열어 공장 함수를 편집합니다.

  1. nano app/__init__.py

강조 표시된 줄을 추가하여 다음 블록과 일치하도록 create_app() 팩터리 함수를 편집합니다.

...
def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here

    # Register blueprints here
    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

파일을 저장하고 닫습니다.

기본 청사진에서 bp 청사진 개체를 가져오고 가독성을 위해 이름을 main_bp로 바꿉니다. 그런 다음 app.register_blueprint() 메서드를 사용하여 Flask가 애플리케이션의 일부로 처리하도록 이 기본 청사진을 등록합니다.

개발 서버가 실행 중인 상태에서 다음 URL로 이동합니다.

http://127.0.0.1:5000/

메인 경로에서 반환한 텍스트인 This is The Main Blueprint라는 텍스트와 함께 페이지가 로드됩니다.

이제 애플리케이션에 경로가 있는 청사진이 있습니다. 다음으로 기본 Blueprint의 기본 경로를 편집하여 HTML 템플릿을 렌더링합니다. 이는 Flask Blueprint로 작업할 때 템플릿을 렌더링하는 방법을 보여줍니다.

수정을 위해 기본 청사진의 routes.py 파일을 엽니다.

  1. nano app/main/routes.py

강조 표시된 줄로 파일을 편집합니다.

from flask import render_template
from app.main import bp

@bp.route('/')
def index():
    return render_template('index.html')

파일을 저장하고 닫습니다.

여기에서 render_template() 함수를 가져와 경로에서 사용하여 index.html이라는 템플릿 파일을 렌더링합니다.

이제 코드 반복을 피하기 위해 다른 모든 템플릿이 공유할 템플릿 디렉토리와 기본 템플릿을 만들어야 합니다.

app 디렉터리 내에 템플릿 디렉터리를 만듭니다.

  1. mkdir app/templates

기본 템플릿으로 사용할 base.html이라는 새 파일을 엽니다.

  1. nano app/templates/base.html

새 파일에 다음 코드를 추가합니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        h2 {
            width: 100%;
        }

        .title {
            margin: 5px;
            width: 100%;
        }

        .content {
            margin: 5px;
            width: 100%;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
        }

        .post {
            flex: 20%;
            padding: 10px;
            margin: 5px;
            background-color: #f3f3f3;
            inline-size: 100%;
        }

        .title a {
            color: #00a36f;
            text-decoration: none;
        }

        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }

    </style>
</head>
<body>
    <nav>
        <a href="{{ url_for('main.index') }}">FlaskApp</a>
        <a href="#">Posts</a>
        <a href="#">Categories</a>
        <a href="#">Questions</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

파일을 저장하고 닫습니다.

이 기본 템플릿에는 다른 템플릿에서 재사용할 HTML 상용구가 있습니다.

기본 템플릿에는 제목 블록, 일부 CSS, 응용 프로그램의 다른 부분에 연결하는 탐색 모음 및 콘텐츠 블록이 있습니다. 기본 템플릿에 대한 자세한 내용은 Flask 애플리케이션에서 템플릿을 사용하는 방법을 참조하세요.

청사진과 함께 url_for() 함수를 사용할 때 blueprint_name.view_function_name 구문을 사용하여 경로에 연결합니다. 인덱스 페이지는 기본 청사진의 index() 뷰 함수에 의해 처리됩니다. 따라서 main.indexurl_for() 함수에 전달하여 링크를 만듭니다.

이제 기본 청사진의 index() 뷰 함수에서 렌더링한 index.html 파일을 생성합니다.

  1. nano app/templates/index.html

새로 생성된 파일에 다음 코드를 추가합니다.

{% extends 'base.html' %}

{% block content %}
    <span class="title"><h1>{% block title %} The Home Page of FlaskApp {% endblock %}</h1></span>
    <div class="content">
        <h2>This is the main Flask blueprint</h2>
    </div>
{% endblock %}

파일을 저장하고 닫습니다.

여기에서 기본 템플릿을 확장합니다. 제목 역할도 하는 <h1> 제목과 인덱스 페이지가 기본 Flask 청사진의 일부임을 나타내는 <h2> 제목을 사용하여 콘텐츠 블록을 교체합니다. .

개발 서버가 실행 중인 상태에서 브라우저를 사용하여 인덱스 페이지를 방문하거나 이미 열려 있는 경우 새로 고칩니다.

http://127.0.0.1:5000/

다음 이미지와 유사한 페이지가 로드됩니다.

이제 청사진을 설정하고 routes.py 파일에 경로를 추가하고 애플리케이션에 등록하고 템플릿을 렌더링했습니다. 다음으로 블로그 게시물에 대한 또 다른 청사진을 만듭니다.

포스트 블루프린트 생성 및 템플릿 렌더링

이제 블로그 게시물의 청사진을 만들고 등록하고 템플릿을 렌더링합니다.

튜토리얼의 이 시점에서 flask_app 디렉토리 구조는 다음과 같습니다(가상 환경의 디렉토리 제외).

.
├── flask_app
    ├── app
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       └── index.html
    └── config.py

블로그 게시물에 대한 새 청사진을 만들려면 이전 섹션과 동일한 단계를 따릅니다.

먼저 청사진 파일을 보관할 새 posts 디렉토리를 만듭니다.

  1. mkdir app/posts

다음으로, 새 posts 디렉터리 내에서 새 __init__.py 파일을 엽니다.

  1. nano app/posts/__init__.py

bp 청사진 개체를 생성하고 생성할 경로를 청사진의 routes.py 파일로 가져옵니다.

from flask import Blueprint

bp = Blueprint('posts', __name__)


from app.posts import routes

파일을 저장하고 닫습니다.

이전 코드 블록에서는 posts를 청사진의 이름으로 사용합니다. 또한 아직 만들지 않은 routes.py 파일에서 경로를 가져옵니다.

다음으로, 게시물 청사진에 대한 경로를 넣을 새 routes.py 파일을 엽니다.

  1. nano app/posts/routes.py

이 파일에 다음 경로를 추가합니다.

from flask import render_template
from app.posts import bp

@bp.route('/')
def index():
    return render_template('posts/index.html')

@bp.route('/categories/')
def categories():
    return render_template('posts/categories.html')

파일을 저장하고 닫습니다.

여기에는 두 개의 경로가 있습니다. 하나는 애플리케이션의 게시물 구성 요소의 색인 페이지 경로이고 다른 하나는 게시물 구성 요소의 일부가 될 카테고리 경로입니다.

index 경로에서 posts/index.html 경로로 템플릿 파일을 렌더링합니다. 즉, Flask는 posts라는 디렉토리를 찾습니다. templates 디렉토리에서 posts 디렉토리 내부의 index.html 파일을 찾습니다.

categories 경로에서 categories.html 템플릿을 렌더링합니다. 이 템플릿은 templates 내의 posts 디렉토리에도 있습니다. 코드> 폴더.

이제 템플릿 디렉토리 내에 새로운 posts 디렉토리를 만듭니다.

  1. mkdir app/templates/posts

다음으로 posts 디렉토리 안에 새로운 index.html 파일을 생성합니다. 이것은 게시물 청사진의 index() 보기 기능에서 렌더링하는 파일입니다.

  1. nano app/templates/posts/index.html

새로 생성된 파일에 다음 코드를 추가합니다.

{% extends 'base.html' %}

{% block content %}
    <span class="title"><h1>{% block title %} The Posts Page {% endblock %}</h1></span>
    <div class="content">
        <h2>This is the posts Flask blueprint</h2>
    </div>
{% endblock %}

파일을 저장하고 닫습니다.

여기에서 기본 템플릿을 확장합니다. 또한 <h1> 제목을 제목으로 설정하고 <h2> 제목을 설정하여 게시물 청사진의 일부로 페이지를 표시합니다.

다음으로 posts 디렉토리 안에 새로운 categories.html 파일을 생성합니다. 이것은 게시물 청사진의 categories() 보기 기능에서 렌더링한 파일입니다.

  1. nano app/templates/posts/categories.html

새로 생성된 파일에 다음 코드를 추가합니다.

{% extends 'base.html' %}

{% block content %}
    <span class="title"><h1>{% block title %} Categories {% endblock %}</h1></span>
    <div class="content">
        <h2>This is the categories page within the posts blueprint</h2>
    </div>
{% endblock %}

파일을 저장하고 닫습니다.

기본 템플릿을 확장하고 <h1> 제목을 제목으로 설정하고 <h2> 제목을 설정하여 페이지를 게시물 청사진의 일부로 표시합니다.

게시물 청사진을 만들고 경로를 추가했으며 렌더링된 템플릿을 만들었습니다. 이제 이 청사진을 Flask가 애플리케이션의 일부로 인식하도록 공장 기능에 등록합니다.

app/__init__.py 파일을 열어 공장 함수를 편집합니다.

  1. nano app/__init__.py

강조 표시된 줄을 추가하여 create_app() 팩터리 함수를 편집합니다.


def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here

    # Register blueprints here
    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    from app.posts import bp as posts_bp
    app.register_blueprint(posts_bp, url_prefix='/posts')

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

파일을 저장하고 닫습니다.

여기서는 posts 청사진 패키지에서 bp 청사진 개체를 가져오고 가독성을 위해 이름을 posts_bp로 변경했습니다.

posts_bp 청사진 개체를 전달하여 app.register_blueprint() 메서드를 사용하여 게시물 청사진을 등록합니다. 또한 url_prefix 매개변수에 대한 값 /posts를 전달하여 청사진의 경로에 이 문자열을 접두사로 붙입니다. 예를 들어 게시물 청사진의 기본 / 경로는 /posts/를 통해 액세스할 수 있으며 /categories 경로는 에 있습니다. >/게시물/카테고리/.

새 게시물 청사진이 등록되고 개발 서버가 실행 중인 상태에서 브라우저를 사용하여 다음 URL로 이동합니다.

http://127.0.0.1:5000/posts/
http://127.0.0.1:5000/posts/categories/

The Posts Page 제목이 http://127.0.0.1:5000/posts/ 페이지에 대해 로드됩니다. 카테고리 제목이 http://127.0.0.1:5000/posts/categories/ 페이지에 로드됩니다.

탐색 모음의 게시물 및 카테고리 링크가 작동하도록 하려면 수정을 위해 기본 템플릿을 엽니다.

  1. nano app/templates/base.html

강조 표시된 식으로 <nav> 태그를 수정합니다.

    <nav>
        <a href="{{ url_for('main.index') }}">FlaskApp</a>
        <a href="{{ url_for('posts.index') }}">Posts</a>
        <a href="{{ url_for('posts.categories') }}">Categories</a>
        <a href="#">Questions</a>
    </nav>

파일을 저장하고 닫습니다.

url_for(posts.index) 함수 호출로 게시물 인덱스에 연결하고 url_for(posts.categories)로 카테고리 페이지에 연결합니다.

게시물 및 카테고리 링크 기능을 활성화하려면 애플리케이션의 페이지를 새로 고칩니다.

이제 애플리케이션에 게시물 청사진이 등록되었습니다. 다음으로 질문과 답변에 대한 청사진을 추가합니다.

질문 블루프린트 생성 및 템플릿 렌더링

이제 질문 청사진을 만들고 등록하고 템플릿을 렌더링합니다.

튜토리얼의 이 시점에서 flask_app 디렉토리 구조는 다음과 같습니다(가상 환경의 디렉토리 제외).

.
├── flask_app
    ├── app
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       └── posts
    │           ├── categories.html
    │           └── index.html
    └── config.py

질문과 답변을 위한 새 청사진을 만들려면 청사진 파일을 보관할 새 questions 디렉터리를 만듭니다.

  1. mkdir app/questions

다음으로, 새 questions 디렉터리 내에서 새 __init__.py 파일을 엽니다.

  1. nano app/questions/__init__.py

bp 청사진 개체를 생성하고 나중에 청사진의 routes.py 파일에서 생성할 경로를 가져옵니다.

from flask import Blueprint

bp = Blueprint('questions', __name__)

from app.questions import routes

파일을 저장하고 닫습니다.

이전 코드 블록에서는 questions를 청사진의 이름으로 사용합니다. 또한 아직 만들지 않은 routes.py 파일에서 경로를 가져옵니다.

다음으로 질문 청사진에 대한 경로를 넣을 새 routes.py 파일을 엽니다.

  1. nano app/questions/routes.py

이 파일에 다음 경로를 추가합니다.

from flask import render_template
from app.questions import bp

@bp.route('/')
def index():
    return render_template('questions/index.html')

파일을 저장하고 닫습니다.

questions 청사진 개체를 사용하여 / 경로를 생성하고 questions라는 디렉터리 내에서 index.html이라는 템플릿 파일을 렌더링합니다. 템플릿 폴더 안에 생성합니다.

템플릿 디렉토리 안에 questions 디렉토리를 만든 다음 그 안에 index.html 파일을 엽니다.

  1. mkdir app/templates/questions
  2. nano app/templates/questions/index.html

새 파일에 다음 코드를 추가합니다.

{% extends 'base.html' %}

{% block content %}
    <span class="title">
        <h1>{% block title %} Questions {% endblock %}</h1>
    </span>
    <div class="questions">
        <h2>Questions Blueprint</h2>
    </div>
{% endblock %}

파일을 저장하고 닫습니다.

여기에서 다른 청사진의 이전 색인 템플릿과 유사하게 제목과 부제목을 설정합니다.

이제 app/__init__.py를 열어 create_app() 팩터리 함수에 질문 청사진을 등록합니다.

  1. nano app/__init__.py

강조 표시된 줄을 추가하여 create_app() 팩터리 함수를 편집합니다.


def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here

    # Register blueprints here
    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    from app.posts import bp as posts_bp
    app.register_blueprint(posts_bp, url_prefix='/posts')

    from app.questions import bp as questions_bp
    app.register_blueprint(questions_bp, url_prefix='/questions')

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

파일을 저장하고 닫습니다.

게시물 청사진에서 했던 것처럼 질문 청사진을 등록하고 해당 경로에 /questions 접두사를 추가합니다.

개발 서버가 실행 중인 상태에서 브라우저를 사용하여 다음 URL로 이동합니다.

http://127.0.0.1:5000/questions/

질문 및 질문 청사진 제목이 페이지에 표시됩니다.

이제 질문 링크가 작동하게 됩니다. 기본 템플릿을 열어 탐색 모음을 편집합니다.

  1. nano app/templates/base.html

강조 표시된 식으로 <nav> 태그를 수정합니다.

    <nav>
        <a href="{{ url_for('main.index') }}">FlaskApp</a>
        <a href="{{ url_for('posts.index') }}">Posts</a>
        <a href="{{ url_for('posts.categories') }}">Categories</a>
        <a href="{{ url_for('questions.index') }}">Questions</a>
    </nav>

파일을 저장하고 닫습니다.

여기에서 url_for(questions.index) 함수 호출을 사용하여 질문 색인 페이지에 연결합니다.

탐색 모음에서 질문 링크 기능을 활성화하려면 응용 프로그램의 페이지를 새로 고칩니다.

애플리케이션의 다양한 구성 요소를 관리하기 위해 여러 청사진을 만들었습니다. 공장 기능에 청사진을 등록하고 각 경로에 대한 템플릿을 렌더링했습니다. 다음으로 애플리케이션에 Flask-SQLAlchemy를 추가하여 Flask 애플리케이션에서 대규모 데이터베이스를 관리하고 구성합니다.

5단계 - Flask 애플리케이션에 Flask-SQLAlchemy 모델 추가

이 단계에서는 Flask-SQLAlchemy를 애플리케이션과 통합하고, 데이터베이스 모델용 디렉터리를 추가하고, 게시물용 모델과 질문용 모델을 만듭니다. 게시물 테이블에 몇 개의 블로그 게시물을 삽입한 다음 게시물의 인덱스 경로를 편집하여 데이터베이스의 모든 게시물을 표시합니다. 또한 몇 가지 질문과 답변을 질문 테이블에 삽입하여 질문 색인 페이지에 표시하고 데이터베이스에 추가 질문과 답변을 추가하기 위한 새로운 웹 양식과 함께 표시합니다.

튜토리얼의 이 시점에서 flask_app 디렉토리 구조는 다음과 같습니다(가상 환경의 디렉토리 제외).

.
├── flask_app
    ├── app
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── questions
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       ├── posts
    │       │   ├── categories.html
    │       │   └── index.html
    │       └── questions
    │           └── index.html
    └── config.py

Flask 확장 관리 및 Flask-SQLAlchemy 통합을 위한 파일 생성

애플리케이션에 Flask-SQLAlchemy 확장을 추가하려면 먼저 다양한 Flask 확장을 설정할 extensions.py라는 Python 모듈을 앱<에 추가합니다. /코드> 디렉토리.

app 디렉터리 내에서 새 extensions.py 파일을 엽니다.

  1. nano app/extensions.py

새로 생성된 파일에 다음 코드를 추가합니다.

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

파일을 저장하고 닫습니다.

여기서는 Flask-SQLAlchemy 패키지에서 SQLAlchemy() 클래스를 가져온 다음 이를 사용하여 인수 없이 db 데이터베이스 객체를 생성합니다.

db 객체를 사용하여 SQLAlchemy를 공장 기능에서 구성하는 Flask 애플리케이션과 통합합니다. app/__init__.py 파일을 열어 공장 함수를 편집합니다.

  1. nano app/__init__.py

파일을 편집하여 데이터베이스 개체를 가져오고 초기화합니다.

from flask import Flask

from config import Config
from app.extensions import db

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here
    db.init_app(app)

    # Register blueprints here
    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    from app.posts import bp as posts_bp
    app.register_blueprint(posts_bp, url_prefix='/posts')

    from app.questions import bp as questions_bp
    app.register_blueprint(questions_bp, url_prefix='/questions')

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

여기에서 이전에 생성한 app.extensions 모듈에서 db 데이터베이스 개체를 가져옵니다. 청사진을 등록하기 전에 db.init_app() 메서드를 사용하여 데이터베이스 객체를 app 애플리케이션 인스턴스에 연결합니다. 이를 통해 db 개체를 사용하여 애플리케이션에서 Flask-SQLAlchemy 모델을 만들고 상호 작용할 수 있습니다.

flask_app 디렉터리 내 config.py 파일의 Config 개체를 사용하여 Flask-SQLAlchemy를 구성했음을 기억하세요. 빠른 알림을 위해 이 파일을 열 수 있습니다.

  1. nano config.py
import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI')\
        or 'sqlite:///' + os.path.join(basedir, 'app.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

DATABASE_URI 환경 변수를 설정하지 않으면 db 개체는 기본적으로 app.db라는 SQLite 파일에 연결됩니다. 데이터베이스 테이블을 생성하면 flask_app 디렉토리에 나타납니다. 검토가 완료되면 파일을 닫습니다.

Flask 셸을 사용하여 데이터베이스가 올바르게 등록되었는지 확인할 수 있습니다. 먼저 가상 환경을 활성화한 상태에서 flask_app 디렉터리에 Flask 환경 변수를 설정했는지 확인하세요.

  1. export FLASK_APP=app
  2. export FLASK_ENV=development

플라스크 셸을 엽니다.

  1. flask shell

app.extensions 모듈에서 db 개체를 가져온 다음 인쇄합니다.

  1. from app.extensions import db
  2. print(db)

다음과 유사한 데이터베이스 경로를 받게 됩니다.

Output
<SQLAlchemy engine=sqlite:///your_path_to_flask_app/app.db>

이 출력은 db 개체가 제대로 등록되었음을 의미합니다. Flask 셸에서 코드를 실행하는 중에 오류가 발생하면 다음 섹션으로 이동하기 전에 팩토리 함수에 db 객체를 올바르게 등록했는지 확인하세요. exit()를 입력하여 Flask 셸을 종료할 수 있습니다.

포스트 모델 생성 및 상호 작용

대규모 애플리케이션에는 수백 개의 데이터베이스 테이블이 있을 수 있으며, 이는 이를 관리하기 위해 수백 개의 SQLAlchemy 모델을 작성해야 함을 의미합니다. 모든 모델을 하나의 파일에 넣으면 애플리케이션을 유지 관리하기가 어려워지므로 모델을 models 디렉토리 내 별도의 Python 파일로 분할합니다. 각 파일은 애플리케이션의 특정 부분과 관련된 모델 및 기능을 보유합니다. 예를 들어, app 디렉토리의 models라는 디렉토리의 post.py 파일 안에 게시물 관리를 위한 모델과 기능을 넣을 수 있습니다.

튜토리얼의 이 시점에서 flask_app 디렉토리 구조는 다음과 같습니다(가상 환경의 디렉토리 제외).

.
├── flask_app
    ├── app
    │   ├── extensions.py
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── questions
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       ├── posts
    │       │   ├── categories.html
    │       │   └── index.html
    │       └── questions
    │           └── index.html
    └── config.py

자체 파일의 게시물에 대한 데이터베이스 모델을 만들려면 먼저 app 디렉토리 안에 models라는 디렉토리를 만듭니다.

  1. mkdir app/models

그런 다음 모델 디렉토리 내에서 post.py라는 새 파일을 엽니다.

  1. nano app/models/post.py

새로 생성된 파일에 다음 코드를 추가합니다.

from app.extensions import db

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(150))
    content = db.Column(db.Text)

    def __repr__(self):
        return f'<Post "{self.title}">'

파일을 저장하고 닫습니다.

app.extensions 모듈에서 db 데이터베이스 개체를 가져옵니다. 그런 다음 db.Model 클래스를 사용하여 Post라는 Flask-SQLAlchemy 데이터베이스 모델을 만듭니다. 모델에는 기본 키(id)로 ID 정수 열, 게시물 제목(title)에 대한 문자열을 포함하는 열 및 텍스트 열이 있습니다. 콘텐츠(콘텐츠). 특별한 __repr__() 메서드를 사용하여 제목을 사용하여 각 게시물 객체에 대한 문자열 표현을 제공합니다. Flask-SQLAlchemy에 대한 자세한 내용은 Flask-SQLAlchemy를 사용하여 Flask 애플리케이션에서 데이터베이스와 상호 작용하는 방법을 검토할 수 있습니다.

다음으로 Flask 셸을 열어 포스트 모델을 기반으로 포스트 테이블을 만듭니다.

  1. flask shell

다음 코드를 실행하여 게시물 테이블을 만듭니다.

  1. from app.extensions import db
  2. from app.models.post import Post
  3. db.create_all()

app.extensions 모듈에서 db 개체를 가져오고 app.models.post에서 Post 모델을 가져옵니다. 기준 치수. 그런 다음 create_all() 메서드를 사용하여 게시물 테이블을 만듭니다.

코드는 출력 없이 실행되어야 합니다. 오류가 발생하면 app/extensions.pyapp/models/post.py 파일을 확인하고 이전 단계를 검토하여 작성된 대로 수행했는지 확인하세요. .

참고: db.create_all() 함수는 이미 존재하는 테이블을 다시 생성하거나 업데이트하지 않습니다. 예를 들어 새 열을 추가하여 모델을 수정하려는 경우 db.create_all() 함수를 실행하면 모델에 대한 변경 사항이 테이블에 적용되지 않습니다. 데이터베이스에 테이블이 이미 있습니다. 해결책은 db.drop_all() 함수를 사용하여 기존 데이터베이스 테이블을 모두 삭제한 다음 db.create_all() 함수를 사용하여 다음과 같이 다시 만드는 것입니다.

  1. db.drop_all()
  2. db.create_all()

이 명령은 수정 사항을 모델에 적용하고 데이터베이스의 모든 기존 데이터를 삭제합니다. 데이터베이스를 업데이트하고 기존 데이터를 보존하려면 Flask-Migrate 확장을 사용하여 Flask 명령줄 인터페이스를 통해 SQLAlchemy 스키마 마이그레이션을 수행해야 합니다.

다음으로 다음 코드를 실행하여 10개의 임의 게시물을 생성합니다.

  1. import random
  2. for i in range(0, 10):
  3. random_num = random.randrange(1, 1000)
  4. post = Post(title=f'Post #{random_num}',
  5. content=f'Content #{random_num}')
  6. db.session.add(post)
  7. print(post)
  8. print(post.content)
  9. print('--')
  10. db.session.commit()

db 데이터베이스 개체, Post 데이터베이스 모델 및 random Python 모듈을 가져옵니다. 이 모듈을 사용하여 난수를 생성하여 제목과 내용이 다른 샘플 게시물을 생성합니다. range() Python 함수와 함께 for 루프를 사용하여 코드 블록을 10회 반복합니다.

for 루프에서 random.randrange() 메서드를 사용하여 1에서 1000 사이의 임의의 정수를 생성합니다. 를 만들고 random_num이라는 변수에 저장합니다. 그런 다음 Post 모델을 사용하여 게시물 개체를 만들고 random_num 변수의 난수를 사용하여 샘플 게시물 제목과 콘텐츠를 생성합니다.

그런 다음 게시물 개체를 데이터베이스 세션에 추가하고 개체 자체와 해당 내용을 인쇄하고 트랜잭션을 커밋합니다.

다음과 유사하지만 숫자가 다른 출력이 표시됩니다.

Output
<Post "Post #58"> Content #58 -- <Post "Post #55"> Content #55 -- <Post "Post #994"> Content #994 -- <Post "Post #394"> Content #394 -- <Post "Post #183"> Content #183 -- <Post "Post #633"> Content #633 -- <Post "Post #790"> Content #790 -- <Post "Post #883"> Content #883 -- <Post "Post #259"> Content #259 -- <Post "Post #581"> Content #581 --

각 게시물에는 임의로 생성된 번호가 첨부되어 있습니다. 이 게시물은 이제 데이터베이스에 있습니다.

Flask 셸을 실행 중인 상태로 두고 새 터미널 창을 엽니다. 환경을 소싱하고 애플리케이션 폴더로 이동합니다.

이제 테이블에 몇 가지 샘플 게시물이 있으므로 게시물의 인덱스 페이지에 표시할 수 있습니다. 먼저 게시물 경로 파일을 열어 색인 경로를 수정합니다.

  1. nano app/posts/routes.py

강조 표시된 줄을 추가하여 가져오기 및 인덱스 경로를 편집합니다.

from flask import render_template
from app.posts import bp
from app.extensions import db
from app.models.post import Post


@bp.route('/')
def index():
    posts = Post.query.all()
    return render_template('posts/index.html', posts=posts)

파일을 저장하고 닫습니다.

db 데이터베이스 개체와 Post 모델을 가져옵니다. 데이터베이스의 모든 게시물을 가져온 다음 게시물의 인덱스 템플릿으로 전달합니다.

수정을 위해 게시물의 인덱스 템플릿을 열어 전달한 게시물을 표시합니다.

  1. nano app/templates/posts/index.html

강조 표시된 줄을 추가하여 파일을 편집합니다.

{% extends 'base.html' %}

{% block content %}
    <span class="title"><h1>{% block title %} The Posts Page {% endblock %}</h1></span>
    <div class="content">
        <h2>This is the posts Flask blueprint</h2>
        {% for post in posts %}
            <div class="post">
                <p><b>#{{ post.id }}</b></p>
                <p class="title">
                    <b>
                        <a href="#">
                            {{ post.title }}
                        </a>
                    </b>
                </p>
                <div class="content">
                    <p>{{ post.content }}</p>
                </div>
                <hr>
            </div>
        {% endfor %}
    </div>
{% endblock %}

파일을 저장하고 닫습니다.

여기에서 게시물을 반복하고 각 게시물의 ID, 제목 및 콘텐츠를 표시합니다.

개발 서버가 실행 중인 상태에서 게시물의 인덱스 페이지를 방문하거나 열려 있는 경우 새로 고칩니다.

http://127.0.0.1:5000/posts/

생성한 샘플 게시물은 다음 이미지와 같이 색인 페이지에 표시됩니다.

이제 게시물에 대한 데이터베이스 모델이 생겼습니다. 이제 게시물 작성, 편집 및 삭제와 같은 새로운 경로 및 템플릿을 사용하여 애플리케이션에 기능을 추가할 수 있습니다.

질문 모델 생성 및 상호 작용

게시물 모델을 생성하고 게시물 청사진에서 상호 작용했습니다. 이제 질문과 답변을 관리하기 위한 질문 데이터베이스 모델을 추가합니다.

튜토리얼의 이 시점에서 flask_app 디렉토리 구조는 다음과 같습니다(가상 환경의 디렉토리 제외).

.
├── flask_app
    ├── app
    │   ├── extensions.py
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── models
    │   │   └── post.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── questions
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       ├── posts
    │       │   ├── categories.html
    │       │   └── index.html
    │       └── questions
    │           └── index.html
    ├── app.db
    └── config.py

질문 데이터베이스 모델을 만들려면 모델 디렉토리에서 question.py라는 새 파일을 엽니다.

  1. nano app/models/question.py

다음 코드를 추가합니다.

from app.extensions import db

class Question(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text)
    answer = db.Column(db.Text)

    def __repr__(self):
        return f'<Question {self.content}>'

파일을 저장하고 닫습니다.

여기서는 app.extensions 모듈에서 db 데이터베이스 개체를 가져옵니다. 그런 다음 db.Model 클래스를 사용하여 Question이라는 모델을 만듭니다. 모델에는 ID 정수 열이 기본 키(id), 질문 내용에 대한 텍스트 열(content) 및 답변에 대한 텍스트 열이 있습니다. (대답). 그런 다음 특수 __repr__() 메서드를 사용하여 콘텐츠를 사용하여 각 질문을 나타냅니다.

Flask 셸을 실행 중인 터미널 세션에서 다음 코드를 실행하여 질문 모델을 기반으로 질문 테이블을 만듭니다.

  1. flask shell

다음 코드를 실행하여 질문 테이블을 만들고 여기에 몇 가지 질문과 답변을 추가합니다.

  1. from app.extensions import db
  2. from app.models.question import Question
  3. db.create_all()
  4. q1 = Question(content='Why is the sky blue?', answer='Because... Why not?')
  5. q2 = Question(content='What is love?', answer='A portal to the underworld.')
  6. db.session.add_all([q1, q2])
  7. db.session.commit()

코드는 출력 없이 실행되어야 합니다. 오류가 발생하면 app/models/question.py 파일을 확인하여 코드가 올바른 구문으로 작성되었는지 확인하세요.

데이터베이스 개체와 질문 모델을 가져온 다음 db.create_all()을 사용하여 테이블을 만들고 마지막으로 두 개의 질문 개체를 데이터베이스 세션에 추가하고 트랜잭션을 커밋합니다.

Flask 셸을 종료합니다.

  1. exit()

이제 질문 청사진에서 새 질문 모델과 상호 작용할 수 있습니다. 이렇게 하려면 쿼리를 수정하기 위해 질문 청사진의 routes.py 파일을 열고 질문 테이블에 있는 질문을 표시합니다.

  1. nano app/questions/routes.py

강조 표시된 줄을 추가하여 파일을 편집합니다.

from flask import render_template
from app.questions import bp
from app.models.question import Question

@bp.route('/')
def index():
    questions = Question.query.all()
    return render_template('questions/index.html', questions=questions)

파일을 저장하고 닫습니다.

여기에서 질문 모델을 가져오고 데이터베이스의 모든 질문을 가져온 다음 질문의 색인 템플릿으로 전달합니다.

다음으로 질문 색인 템플릿에 전달한 질문을 표시하고 사용자가 새 질문을 추가할 수 있도록 웹 양식을 추가합니다. 질문의 템플릿 디렉토리에서 index.html 파일을 엽니다.

  1. nano app/templates/questions/index.html

강조 표시된 줄을 추가하여 파일을 편집합니다.

{% extends 'base.html' %}

{% block content %}
    <span class="title">
        <h1>{% block title %} Questions {% endblock %}</h1>
    </span>
    <div class="questions">
        <h2>Questions Blueprint</h2>

        <div class="question">
            <div class="new-question">
                <form method="POST">
                    <p>
                        <textarea id="q-content"
                                name="content"
                                placeholder="Question"
                                cols="30" rows="3"></textarea>
                    </p>
                    <textarea id="q-answer"
                            name="answer"
                            placeholder="Answer"
                            cols="30" rows="3"></textarea>
                    <p><input type="submit"></p>
                </form>
            </div>
            <div class="questions-list">
                {% for question in questions %}
                    <div class="question">
                        <h4>{{ question.content }}</h4>
                        <p>{{ question.answer }}</p>
                        <hr>
                    </div>
                {% endfor %}
            </div>
        </div>

    </div>
{% endblock %}

파일을 저장하고 닫습니다.

여기에서 두 개의 텍스트 영역이 있는 양식을 만듭니다. 하나는 질문 내용용이고 다른 하나는 답변용입니다. 그런 다음 양식에 제출 버튼을 추가합니다.

양식 아래에서 질문의 인덱스 경로에서 전달한 questions 변수를 반복하여 각 질문의 내용과 답변을 표시합니다.

개발 서버가 실행 중인 상태에서 브라우저를 사용하여 질문 인덱스 페이지로 이동합니다.

http://127.0.0.1:5000/questions/

청사진 제목, 제출 양식 및 두 가지 샘플 질문과 함께 페이지가 로드됩니다.

그러나 양식을 작성하고 제출하면 양식이 POST 요청을 질문의 색인 경로로 보내지만 경로는 POST 요청을 수락하거나 처리하지 않습니다. 이 문제를 해결하고 양식이 작동하도록 하려면 질문 청사진의 인덱스 경로를 수정하고 양식 데이터를 사용하여 데이터베이스에 새 질문을 추가합니다.

질문 청사진의 routes.py 파일을 엽니다.

  1. nano app/questions/routes.py

강조 표시된 줄을 추가하여 파일을 편집합니다.

from flask import render_template, request, url_for, redirect
from app.questions import bp
from app.models.question import Question
from app.extensions import db

@bp.route('/', methods=('GET', 'POST'))
def index():
    questions = Question.query.all()

    if request.method == 'POST':
        new_question = Question(content=request.form['content'],
                                answer=request.form['answer'])
        db.session.add(new_question)
        db.session.commit()
        return redirect(url_for('questions.index'))

    return render_template('questions/index.html', questions=questions)

파일을 저장하고 닫습니다.

(GET, POST) 튜플을 methods 매개변수에 전달하여 GETPOST 메소드를 허용합니다. if request.method == POST: 조건에서 POST 요청을 처리합니다. 여기에서 request.form 개체에서 가져온 콘텐츠와 사용자가 제출한 답변을 사용하여 새 질문 개체를 만듭니다. 새 질문을 데이터베이스 세션에 추가하고 트랜잭션을 커밋한 다음 사용자를 질문 인덱스 페이지로 리디렉션합니다.

이제 양식이 작동하고 데이터베이스에 새 질문과 답변을 추가할 수 있습니다. http://127.0.0.1:5000/questions/ URL에서 이 기능을 테스트할 수 있습니다.

Flask-SQLAlchemy를 애플리케이션과 통합하여 코드를 구성할 모델용 디렉터리를 추가했습니다.

최종 파일을 DigitalOcean 커뮤니티 저장소에 있는 코드와 비교할 수 있습니다.

결론

청사진을 사용하여 대규모 Flask 애플리케이션을 구성하고 템플릿과 모델로 구성했습니다. 각 구성 요소에 자체 경로, 템플릿 및 모델이 있도록 설정합니다.

이제 예제 웹 응용 프로그램에는 다양한 방식으로 확장할 수 있는 세 가지 주요 구성 요소가 있습니다.

  • 기본 청사진: 사용자가 애플리케이션 소유자에게 연락할 수 있도록 정보 페이지 또는 연락처 페이지를 추가할 수 있습니다.\n
  • 게시물 청사진: 게시물 작성, 편집, 삭제 및 정렬을 위한 페이지를 추가할 수 있습니다. Flask-SQLAlchemy와 다대다 데이터베이스 관계를 사용하여 게시물에 태그를 추가할 수도 있습니다.\n
  • 질문 청사진: 질문을 관리하기 위한 페이지를 추가하고 Flask-SQLAlchemy와 일대다 데이터베이스 관계를 사용하여 질문에 여러 솔루션이 있을 수 있도록 답변을 위한 다른 테이블을 만들 수 있습니다.\n

인증, 결제, 관리 등과 같은 기능에 대한 청사진을 더 추가할 수도 있습니다.

Flask에 대해 자세히 알아보려면 Flask로 웹 애플리케이션을 구축하는 방법 시리즈의 다른 자습서를 확인하세요.