プログラミング

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

投稿日:

「ログイン機能を作る」の【Part8】いってみましょう。
前回は「ログイン処理」を変更しました。
今回からは「新規アカウント作成」の機能を作っていこうと思います。

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

では「アカウント作成」の機能とページを作成していきます。

まずは登録したい「名前」と「メールアドレス」を入力する「フォーム」を作成します。
「フォーム」の作成は前の記事でもやったのでそちらをご覧ください。

「入力フォーム」の作成はこちら。

新規のアカウントを作成するうえで「アカウント内容の重複」は避けなけらばなりません。
登録する「名前」と「メールアドレス」はユーザーごとに違っていないとだめですよね。

ですので「バリデーション」というものを追加したいと思います。

「バリデーション」についてはこちら。

バリデーションを追加しよう

「バリデーション」を追加するために「wtforms.validators」から「ValidationError」をインポートしていきましょう。

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('アカウント作成')

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

@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')

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

バリデーション処理を記述しよう

「アカウント作成ボタン」が押された際に「入力されたデータ」と「データベースのデータ」を照合し、同じものがないか確認します。

「validation_」+「フィールド名(今回はnameとmail)」で簡単に「バリデーション」を追加できます。

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')

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

まとめ

今回は「入力フォーム」と「バリデーション」を設定しました。
次回は「テンプレートの作成(entry.html)」と「アカウント登録処理」を追加していきます。
それではまた。

-プログラミング
-

執筆者:


  1. […] 【Python】ログイン機能を作る「Flask-Login」⑧ […]

comment

メールアドレスが公開されることはありません。

関連記事

【Python】Excelに画像を貼り付けてみよう

前回は「openpyxl」を使って、セルに値を入力することができました。今回は、セルに値ではなく、「画像」を貼り付けてみたいと思います。 openpyxlで画像を貼り付けてみよう 「openpyxl」 …

【WTForms】IntegerFieldを使ってみる

今回は「wtforms」の「IntegerField」を使ってみたいと思います。 IntegerFieldを使ってみる 「Integer」とは「整数」という意味です。なので「整数」のみ受け取るフォーム …

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

「ログイン機能を作る」【Part5】を書いていきます。前回作成した「入力フォーム」からログインできる機能を追加していきます。 ログイン機能を追加しよう 今回は、決められた「name(名前)」,「mai …

【Python】ANACONDAのインストール

今回は実際に「ANACONDA」をインストールしていきます。既にPythonをインストールしている方はアンインストールしといたほうがいいみたいですね。 ANACONDAのインストール ではまずソフトを …

ローカル掲示板①

今回はPHPの学習を兼ねて掲示板を作っていきます。 ①ベース作成 まずは掲示板のベースを作っていきます。HTMLを使いますね。 とりあえずこんな感じにします。 <!DOCTYPE html&gt …

YouTube