【Python】ログイン機能を作る「Flask-Login」⑨

「ログイン機能を作る」の【Part9】をやっていきます。
前回は「新規アカウント作成」の「入力フォーム」と「バリデーション」を作りました。
今回は残りの「テンプレートの作成(entry.html)」と「アカウント登録処理」をやっていこうと思います。

アカウントの登録機能を作ろう

では「テンプレート(entry.html)」と「アカウント登録処理」を作っていきます。

前回の記事はこちら。

テンプレートを作成しよう

「テンプレートの作成」については以前に作成した記事があるので
そちらをご覧ください。

今回追加する「テンプレート」は「entry.html」とします。

<html>
  <head>
    <title>Entry</title>
  </head>
  <body>
    <h1>アカウント作成</h1>
    <p>
      <form method="POST" action="{{url_for('entry')}}">
        {{ entry.csrf_token }}

        {{ entry.name.label }}:{{ entry.name }} <br>
        {% for error in entry.name.errors %}
        <span style="color: red;">{{ error }}</span>
        {% endfor %}<br>

        {{ entry.mail.label }}:{{ entry.mail }}<br>
        {% for error in entry.mail.errors %}
        <span style="color: red;">{{ error }}</span>
        {% endfor %}<br>

        {{ entry.submit}}
     </form>
     <li><a href='/'>TOPに戻る</a></li>
    </p>
  </body>
</html>

続いて「ログイン登録処理」の機能を作成していきます。

ログイン登録処理を作成しよう

「entry.html」内で「新規アカウント登録」をしてもらい「データベース」に登録する機能を追加していきます。

from flask import Flask, render_template, redirect
from flask_login import LoginManager, login_required, UserMixin, login_user, logout_user
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import ValidationError
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
login_manager = LoginManager()
login_manager.init_app(app)
app.config['SECRET_KEY'] = "secret"

db_uri = 'sqlite:///login.db'
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
db = SQLAlchemy(app)

class User(UserMixin, db.Model):
    __tablename__ = 'User'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Text())
    mail = db.Column(db.Text())
    def __init__(self, name, mail):
      self.name = name
      self.mail = mail

db.create_all()

class LoginForm(FlaskForm):
  name = StringField('名前')
  mail = StringField('メールアドレス')
  submit = SubmitField('ログイン')

class EntryForm(FlaskForm):
  name = StringField('名前')
  mail = StringField('メールアドレス')
  submit = SubmitField('アカウント作成')

  def validate_name(self, name):
    if User.query.filter_by(name=name.data).one_or_none():
      raise ValidationError('この名前はすでに使われています')

  def validate_mail(self, mail):
    if User.query.filter_by(mail=mail.data).one_or_none():
      raise ValidationError('このメールアドレスはすでに使われています')

@login_manager.user_loader
def load_user(user_id):
  return User.query.get(int(user_id))

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

@app.route('/member')
@login_required
def member():
  return render_template('member.html')

@app.route('/login', methods=['GET','POST'])
def login():
  form = LoginForm()
  if form.validate_on_submit():
    if User.query.filter_by(name=form.name.data, mail=form.mail.data).one_or_none():
      user = User.query.filter_by(name=form.name.data).one_or_none()
      login_user(user)
      return redirect('/member')
    else:
      return 'ログインに失敗しました'
  return render_template('login.html',form=form)

@app.route('/logout')
def logout():
  logout_user()
  return render_template('logout.html')

---------------------------------------------------------------

@app.route('/entry', methods=['GET','POST'])
def entry():
  entry = EntryForm()
  if entry.validate_on_submit():
    newuser = User(name=entry.name.data, mail=entry.mail.data)
    db.session.add(newuser)
    db.session.commit()
    return redirect('/login')
  return render_template('entry.html', entry=entry)

---------------------------------------------------------------

if __name__ == "__main__":
    app.run(host="localhost", debug=True)

「入力フォーム」に入力された「名前」と「メールアドレス」が「newuser」に格納され「データベース」に登録します。

前回作成した「バリデーション」により、重複した「名前」と「メールアドレス」は、はじかれてしまいますね。

では試してみましょう。

新規アカウント登録してみよう

動画でご覧ください。

流れ

  1. 会員ページにアクセス(はじかれる)
  2. アカウント作成前にログイン(ログイン失敗)
  3. 新規アカウント登録
  4. ログイン
  5. 会員ページに飛ぶ
  6. ログアウト
  7. 会員ページにアクセス(はじかれる)
  8. 再度ログイン

こんな感じで試しています。

※今回から「TOPに戻る」リンクを付けました。

まとめ

これで「Flask-Login」の基礎的な使い方を学習できましたかね。
つまづくところもありましたが比較的簡単に作成できたと思います。
ぜひ参考にしてみてください。
それではまた。

  • X

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です