[오늘의 배움] 029 플라스크 회원가입 기능 구현

이상민·2021년 1월 4일
0

[오늘의 배움]

목록 보기
33/70
post-thumbnail

1. 회원 정보 모델 만들기

1) 필요 정보가 다음과 같다고 가정하고 모델을 만든다

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(150), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

이때 id는 인스턴스 추가 시 자동으로 증가한다.

2) flask db migrate, flask db upgrade로 수정된 모델을 DB에 반영한다

2. 회원가입 폼 만들기

1) 필요 필드를 바탕으로 플라스크 폼 클래스를 만든다

class UserCreateForm(FlaskForm):
    username = StringField('사용자이름', validators=[DataRequired(), Length(min=3, max=25)])
    password1 = PasswordField('비밀번호', validators=[
        DataRequired(), EqualTo('password2', '비밀번호가 일치하지 않습니다')])
    password2 = PasswordField('비밀번호확인', validators=[DataRequired()])
    email = EmailField('이메일', validators=[DataRequired(), Email()])
  • PasswordField와 EmailField는 폼을 이용해 템플릿 코드를 자동 생성할 때
    <input type="password"> <input type="email">이 된다.

2) 이메일 검증을 사용하기위해 email-validator를 설치한다

pip3 install email_validator

3. 회원가입 화면 만들기

1) 회원가입 뷰 만들기

from flask import Blueprint, url_for, render_template, flash, request
from werkzeug.security import generate_password_hash
from werkzeug.utils import redirect

from pybo import db
from pybo.forms import UserCreateForm
from pybo.models import User

bp = Blueprint('auth', __name__, url_prefix='/auth')


@bp.route('/signup/', methods=('GET', 'POST'))
def signup():
    form = UserCreateForm()
    if request.method == 'POST' and form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if not user:
            user = User(username=form.username.data,
                        password=generate_password_hash(form.password1.data),
                        email=form.email.data)
            db.session.add(user)
            db.session.commit()
            return redirect(url_for('main.index'))
        else:
            flash('이미 존재하는 사용자입니다.')
    return render_template('auth/signup.html', form=form)
  • flash()는 프로그램 논리 오류를 발생시키는 함수이다
  • generate_password_hash 함수로 암호화한 데이터는 복호화할 수 없다.
    로그인할 때 입력받은 비밀번호는 암호화하여 저장된 비밀번호와 비교한다.

2) 블루프인트 등록하기

app.register_blueprint(auth_views.bp)

3) 회원가입 템플릿 작성하기

{% extends "base.html" %}
{% block content %}
<div class="container my-3">
    <form method="post" class="post-form">
        {{ form.csrf_token }}
        {% include "form_errors.html" %}
        <div class="form-group">
            <label for="username">사용자 이름</label>
            <input type="text" class="form-control" name="username" id="username"
                   value="{{ form.username.data or '' }}">
        </div>
        <div class="form-group">
            <label for="password1">비밀번호</label>
            <input type="password" class="form-control" name="password1" id="password1"
                   value="{{ form.password1.data or '' }}">
        </div>
        <div class="form-group">
            <label for="password2">비밀번호 확인</label>
            <input type="password" class="form-control" name="password2" id="password2"
                   value="{{ form.password2.data or '' }}">
        </div>
        <div class="form-group">
            <label for="email">이메일</label>
            <input type="text" class="form-control" name="email" id="email"
                   value="{{ form.email.data or '' }}">
        </div>
        <button type="submit" class="btn btn-primary">생성하기</button>
    </form>
</div>
{% endblock %}
  • 폼오류와 flash 오류를 표시하는 form_error.html을 include 한다

4) form_error.html 작성하기

<!-- 필드오류 -->
{% for field, errors in form.errors.items() %}
<div class="alert alert-danger" role="alert">
    <strong>{{ form[field].label }}</strong>: {{ ', '.join(errors) }}
</div>
{% endfor %}
<!-- flash 오류 -->
{% for message in get_flashed_messages() %}
<div class="alert alert-danger" role="alert">
    {{ message }}
</div>
{% endfor %}

profile
편하게 읽기 좋은 단위의 포스트를 추구하는 개발자입니다

0개의 댓글