객체지향의 클래스처럼 html 템플릿도 상속할 수 있다
상위 템플릿 HTML 파일을 작성한 뒤 하위 템플릿에서 구현할 내용은 {% block content %} {% endblock %} 템플릿 태그로 비워놓을 수 있다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap.min.css') }}">
<title>Hello, pybo!</title>
</head>
<body>
<!-- 기본 템플릿 안에 삽입될 내용 Start -->
{% block content %}
{% endblock %}
<!-- 기본 템플릿 안에 삽입될 내용 End -->
</body>
</html>
상속 받을 템플릿에서는 {% extends '파일이름.html' %}로 상속받고 {% block content %} {% endblock %}태그 안에 구현한다.
{% extends 'base.html' %}
{% block content %}
<div class="container my-3">
<table class="table">
(... 생략 ...)
</table>
</div>
{% endblock %}
CSRF를 방지하기 위해 필요한 환경변수
CSRF : cross-site request forgery의 약자로 사용자 요청의 위조해 웹사이트 취약점을 공격하는 기법
지정된 시크릿키를 기반으로 CSRF 토큰을 생성하고 이는 전송된 데이터가 실제 웹페이지에서 작성된 데이터인지 판단하게 해줌
프로젝트 루트 디렉토리의 config.py에 SECRET_KEY="문자열"로 설정
플라스크에서는 폼을 사용하기 위해 Flask-WTF 라이브러리를 사용
템플릿에서 폼 태그 바로 밑에 {{ form.csrf_token }}을 추가해 전달한다
폼의 속성, 필드, validator 등을 설정하여 클래스를 만들 수 있다
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField
from wtforms.validators import DataRequired
class QuestionForm(FlaskForm):
subject = StringField('제목', validators=[DataRequired()])
content = TextAreaField('내용', validators=[DataRequired()])
subject = StringField('제목', validators=[DataRequired('제목은 필수입력 항목입니다.')])
form.errors.item()을 이용해 사용자에게 쉽게 오류를 표시할 수 있다.
템플릿에 아래를 추가해 오류를 표시할 수 있다.
{% for field, errors in form.errors.items() %}
<div class="alert alert-danger" role="alert">
<strong>{{ form[field].label }}</strong>: {{ ', '.join(errors) }}
</div>
{% endfor %}
제목과 내용을 작성하지않고 저장하기를 눌러 오류가 발생한 모습