이 문서에서는 Visual Studio Flask 웹 프레임워크로 작업하기자습서 시리즈의 2단계를 제공합니다.
Visual Studio를 사용하면 프로젝트에 대한 보다 광범위한 시작점을 제공하는 프로젝트 템플릿에서 Flask 애플리케이션을 만들 수 있습니다. 자습서 1단계에서는 모든 코드가 단일 파일에 있는 한 페이지로 Flask 앱을 만드는 방법을 설명합니다. 2단계에서는 코드를 리팩터링하고 페이지 템플릿에 대한 구조를 만들어 추가 개발을 가능하게 합니다. 특히 애플리케이션 뷰에 대한 코드를 시작 코드와 같은 다른 측면과 구분하려고 합니다.
자습서의 2단계에서는 다음 방법을 알아봅니다.
- 시작 코드와 뷰를 구분하도록 애플리케이션 코드 리팩터링
- 페이지 템플릿을 사용하여 보기 렌더링
필수 구성 요소
추가 개발을 위해 Flask 프로젝트 리팩터링
빈 Flask 웹 프로젝트 템플릿을 사용하면 시작 코드와 단일 보기를 포함하는 하나의 app.py 파일을 통해 프로젝트를 만들 수 있습니다. 여러 보기 및 템플릿이 있는 앱의 추가 개발을 허용하려면 이러한 함수를 분리해야 합니다.
다음 단계에 따라 Flask 프로젝트를 조정하여 추가 개발을 허용합니다.
솔루션 탐색기Flask 프로젝트 폴더(BasicProject)를 마우스 오른쪽 단추로 클릭하고 >새 폴더 추가선택합니다.
HelloFlask 새 애플리케이션 폴더의 이름을 지정합니다.
HelloFlask 폴더를 마우스 오른쪽 단추로 클릭하고 추가>새 항목 선택하여 새 파일을 만듭니다.
새 항목 추가 대화 상자에서 빈 Python 파일 파일 템플릿을 선택합니다.
파일 이름을 __init__.py. 파일 이름에는 init단어 주위에 두 개의 선행 및 두 개의 끝 밑줄 문자(
_
)가 포함되어야 합니다.추가를 선택합니다.
Flask
인스턴스를 만들고 애플리케이션 뷰를 로드하는 새 파일에 다음 코드를 추가합니다.from flask import Flask app = Flask(__name__) import HelloFlask.views
HelloFlask 폴더에서 views.py이라는 또 다른 새 Python 파일을 만듭니다.
중요하다
파일 이름을 views.py지정해야 합니다.
import HelloFlask.views
문장이 있는 __init__.py 파일 때문에 뷰 이름이 중요합니다. 보기 이름이 두 인스턴스에서 동일하지 않은 경우 Visual Studio는 런타임에 오류를 표시합니다.views.py 파일에 다음 코드를 추가합니다. 이 코드는 함수의 이름을 바꾸고
/home
엔드포인트에 대한 반환 경로를 정의합니다.from flask import Flask from HelloFlask import app @app.route('/') @app.route('/home') def home(): return "Hello Flask!"
또한 이 코드는 app.py 파일의 페이지 렌더링 코드를 포함하고 __init__.py 파일에 선언된
app
개체를 가져옵니다.HelloFlask 폴더에서 템플릿이라는 하위 폴더를 만듭니다. 지금은 폴더가 비어 있습니다.
Flask 프로젝트 폴더(BasicProject)에서 app.py 파일의 내용을 다음 코드로 바꿉니다.
import os from HelloFlask import app # Imports the code from HelloFlask/__init__.py if __name__ == '__main__': HOST = os.environ.get('SERVER_HOST', 'localhost') try: PORT = int(os.environ.get('SERVER_PORT', '5555')) except ValueError: PORT = 5555 app.run(HOST, PORT)
코드를 업데이트한 후 app.py 파일의 이름을 runserver.py로 변경하십시오.
리팩터링된 Flask 프로젝트 구조가 다음 예제와 같이 표시되는지 확인합니다.
리팩터링된 프로그램 실행 및 경로 확인
이제 Visual Studio에서 프로젝트를 실행할 준비가 되었습니다.
Visual Studio에서 디버그 >디버깅 시작(F5)을 선택하거나 주 도구 모음에서 Web Server 선택합니다(표시되는 브라우저는 다를 수 있음).
브라우저에서 애플리케이션이 열리면 브라우저에서
/
(루트) 및/home
URL 경로 엔드포인트를 모두 시도합니다.
디버거에서 업데이트된 프로그램 실행
코드의 다양한 부분에서 중단점을 설정하고 디버거앱 시작 시퀀스를 따를 수도 있습니다.
다음 점과 같은 여러 중단점을 설정합니다.
- runserver.py 파일의 첫 번째 줄
- __init__.py 파일의 첫 번째 줄
-
views.py 파일의
return "Hello Flask!"
줄
디버그> 디버깅 시작 또는 F5를 선택하여 디버거에서 앱을 시작합니다.
디버거 실행되는 동안 F10사용하여 코드를 단계별로 실행하거나 F5사용하여 각 중단점에서 코드를 실행합니다. Visual Studio의 기본 도구 모음에서 계속, 중지, 다시 시작 및 단계 옵션과 같은 디버깅 컨트롤을 사용할 수도 있습니다.
** 작업이 완료되면 먼저 을 선택하고, 이어서 Ctrl+C를 누른 후, 아무 키나 눌러 애플리케이션을 중지합니다. 경로에 대해 열려 있는 브라우저 창을 닫을 수도 있습니다.
소스 제어에 변경 내용 커밋
코드를 리팩터링하고 업데이트를 테스트한 후 변경 내용을 검토하고 소스 제어에 커밋할 수 있습니다.
Ctrl+S 바로 가기 키와 같은 변경 내용을 프로젝트 파일에 저장합니다.
Git 컨트롤 막대에서 커밋되지 않은 변경 내용(연필 5)을 선택하여 Git 변경 내용 창을 엽니다.
Git 변경 내용 창에서 커밋 메시지를 입력하고 모든 변경사항 커밋을 선택합니다.
커밋이 완료되면 Visual Studio는 로컬로 만든 <해시> 커밋메시지를 표시합니다.
(선택 사항) 커밋된 변경 내용을 원격 리포지토리에 푸시합니다.
Git 컨트롤 막대에서 나가는/들어오는 커밋(화살표 1/0)을 선택합니다.
동기화(끌어오기 후 푸시) 또는 푸시를 선택하십시오.
Visual Studio 2022에서 원격 리포지토리에 커밋을 푸시하는 방법을 보여 주는
원격 리포지토리에 푸시하기 전에 여러 로컬 커밋을 누적할 수도 있습니다.
Ctrl+S 바로 가기 키와 같은 변경 내용을 프로젝트 파일에 저장합니다.
Visual Studio의 오른쪽 아래에서 커밋되지 않은 변경 내용(연필 5)을 선택하면 팀 탐색기열립니다.
팀 탐색기에서 "코드 리팩터링"과 같은 커밋 메시지를 입력하고, 커밋 전체를 선택합니다.
커밋이 완료되면 Visual Studio는 로컬로 만든 커밋 <해시>메시지를 표시합니다. 동기화하여 변경 내용을 서버와 공유합니다.
(선택 사항) 커밋된 변경 내용을 원격 리포지토리에 푸시합니다.
팀 탐색기동기화 선택합니다.
외부 커밋을 확장한 다음 푸시를 선택합니다.
원격 리포지토리에 푸시하기 전에 여러 로컬 커밋을 누적할 수도 있습니다.
이 자습서 시리즈의 후속 절차는 이 섹션을 참조하여 소스 제어에 변경 내용을 커밋하는 단계를 참조할 수 있습니다.
커밋 및 푸시 빈도 확인
소스 제어에 변경 내용을 커밋하면 변경 로그에 레코드가 생성되고 필요에 따라 리포지토리를 되돌릴 수 있는 지점이 만들어집니다. 각 커밋을 검사하여 특정 변경 내용을 검토할 수도 있습니다.
Git의 커밋은 저렴합니다. 많은 수의 변경 내용을 누적하고 단일 커밋으로 제출하는 대신 자주 커밋하는 경우 변경 내용을 소량으로 제출하는 것이 좋습니다.
개별 파일에 대한 모든 작은 변경 내용을 커밋할 필요는 없습니다. 기능을 추가하거나, 자습서 시리즈의 이 단계에 표시된 대로 구조를 변경하거나, 일부 코드를 리팩터링할 때 커밋을 하는 것이 일반적입니다. 또한 공동 작업자와 함께 모든 사람에게 가장 적합한 커밋의 세분성에 동의하는 것이 좋습니다.
커밋 빈도와 원격 리포지토리에 커밋을 푸시하는 빈도는 서로 다른 두 가지 문제입니다. 원격 리포지토리에 푸시하기 전에 로컬 리포지토리에 여러 커밋을 누적할 수 있습니다. 커밋 빈도는 팀이 리포지토리를 관리하는 방법에 따라 달라집니다.
템플릿을 사용하여 페이지 및 뷰 렌더링
views.py 파일의 home
함수는 페이지에 대한 일반 텍스트 HTTP 응답을 생성합니다. 대부분의 실제 웹 페이지는 라이브 데이터를 통합하는 풍부한 HTML 페이지로 응답합니다. 개발자가 함수를 사용하여 뷰를 정의하는 주된 이유는 동적으로 콘텐츠를 생성하기 위해서입니다.
뷰의 반환 값은 문자열일 뿐입니다. 동적 콘텐츠를 사용하여 문자열 내에서 HTML을 빌드할 수 있습니다. 태그를 데이터와 구분하는 것이 가장 좋으므로 태그를 템플릿에 배치하고 데이터를 코드에 유지하는 것이 좋습니다.
인라인 HTML을 사용하도록 보기 조정
첫 번째 단계는 일부 동적 콘텐츠가 있는 페이지에 인라인 HTML을 사용하도록 보기 처리를 변환하는 것입니다.
views.py 파일의 내용을 다음 코드로 바꿉니다.
from datetime import datetime from flask import render_template from HelloFlask import app @app.route('/') @app.route('/home') def home(): now = datetime.now() formatted_now = now.strftime("%A, %d %B, %Y at %X") html_content = "<html><head><title>Hello Flask</title></head><body>" html_content += "<strong>Hello Flask!</strong> on " + formatted_now html_content += "</body></html>" return html_content
변경 내용을 저장하고 앱을 다시 실행합니다.
페이지를 몇 번 새로 고쳐 날짜 및 시간이 업데이트되는지 확인합니다. 완료되면 앱을 중지합니다.
HTML 템플릿 만들기
다음으로, HTML 템플릿을 사용하도록 페이지 렌더링 프로세스를 변환합니다.
템플릿 폴더를 마우스 오른쪽 단추로 클릭하고 추가>새 항목 선택하여 새 파일을 만듭니다.
새 항목 추가 대화 상자에서 HTML 페이지 파일 템플릿을 선택합니다. 파일 이름을 index.html로 지정하고 추가를 선택합니다.
HTML 파일의 제공된 내용을 다음 태그로 바꿉니다.
<html> <head> <title>Hello Flask</title> </head> <body> {{ content }} </body> </html>
이 코드에서
{{ content }}
문은 코드에서 값을 제공하는 자리 표시자 또는 대체 토큰(템플릿 변수이라고도 함)입니다.
템플릿을 로드하도록 홈 함수 조정
render_template
메서드를 사용하도록 home
함수를 수정해야 합니다. 이 메서드는 HTML 템플릿을 로드하고 자리 표시자의 이름과 일치하는 명명된 인수를 사용하여 {{ content }}
값을 제공합니다.
views.py 파일에서
home
함수 정의를 다음 코드로 바꿉다.def home(): now = datetime.now() formatted_now = now.strftime("%A, %d %B, %Y at %X") return render_template( "index.html", content = "<strong>Hello, Flask!</strong> on " + formatted_now)
Flask는 템플릿 폴더에서 템플릿을 자동으로 찾으므로 템플릿 경로는 해당 폴더를 기준으로 합니다.
프로젝트 변경 내용을 저장하고 앱을 다시 실행합니다.
템플릿 엔진(Jinja)이 HTML 콘텐츠를 자동으로 이스케이프하므로
content
값 내의 인라인 HTML 구문(\<strong>
...)은 HTML로 렌더링되지 않습니다. 자동 이스케이프는 삽입 공격에 대한 실수로 인한 취약성을 방지합니다.개발자는 종종 한 페이지에서 입력을 수집하고 템플릿 자리 표시자를 사용하여 다른 페이지에서 값으로 사용합니다. 이스케이프는 HTML을 코드에 포함하지 않도록 하는 것이 가장 좋다는 점을 상기시켜 줍니다.
완료되면 앱을 중지합니다.
고유 자리 표시자 사용
HTML 태그 내의 각 데이터 조각에 대해 고유한 자리 표시자를 사용할 수 있습니다. 그런 다음 home
함수를 다시 조정하여 특정 자리 표시자 값을 제공합니다.
index.html 파일의 내용을 다음 태그로 바꿉니다.
<html> <head> <title>{{ title }}</title> </head> <body> <strong>{{ message }}</strong>{{ content }} </body> </html>
views.py 파일에서
home
함수 정의를 다음 코드로 바꿔 모든 자리 표시자에 대한 값을 제공합니다.def home(): now = datetime.now() formatted_now = now.strftime("%A, %d %B, %Y at %X") return render_template( "index.html", title = "Hello Flask", message = "Hello, Flask!", content = " on " + formatted_now)
변경 내용을 저장하고 앱을 다시 실행합니다. 이번에는 올바르게 렌더링된 출력이 표시됩니다.
변경 내용을 소스 제어에 커밋하고 원격 리포지토리를 업데이트할 수 있습니다. 자세한 내용은 변경 내용을 소스 제어에 커밋하는 것을 참조하세요.
페이지 서식 파일 구분
템플릿은 일반적으로 별도의 HTML 파일에서 유지 관리되지만 인라인 템플릿을 사용할 수도 있습니다. 태그와 코드를 완전히 분리하려면 별도의 파일을 사용하는 것이 좋습니다.
템플릿에 .html 확장 사용
페이지 템플릿 파일의 .html 확장은 전적으로 선택 사항입니다.
render_template
함수에 대한 첫 번째 인수에서 파일에 대한 정확한 상대 경로를 항상 식별할 수 있습니다. 그러나 Visual Studio(및 기타 편집기)는 일반적으로 .html 파일을 사용하여 코드 완성 및 구문 색 지정과 같은 기능을 제공하며 이는 페이지 템플릿이 HTML이 아니라는 사실보다 큽니다.
Flask 프로젝트를 사용하는 경우 Visual Studio는 편집 중인 HTML 파일이 실제로 Flask 템플릿인지 자동으로 검색하고 특정 자동 완성 기능을 제공합니다. Flask 페이지 템플릿 주석({#
)을 입력하기 시작하면 Visual Studio에서 닫는 #}
문자를 자동으로 제공합니다.
주석 선택 및 주석 제거 선택 명령(편집>고급 메뉴)에서도 HTML 주석 대신 템플릿 주석을 사용합니다.
템플릿을 하위 폴더로 구성
하위 폴더를 사용한 다음 render_template
함수 호출에서 템플릿 폴더 아래의 상대 경로를 참조할 수 있습니다. 이 방법은 템플릿에 대한 네임스페이스를 효과적으로 만드는 좋은 방법입니다.