プログラミング学習

【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】ログイン機能を作る「Flask-Login」⑨

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

【Python】Flaskで掲示板を作ってみよう②

「Flaskで掲示板を作ってみよう①」から、間が空きましたが続きを書いていきたいと思います。今回は、実際に動作したコードを紹介します。 前回の記事はこちら 【Python】Flaskで掲示板を作ってみ …

【Python】Excelファイルを読み込もう

前回作成したExcelファイルを読み込んでみたいと思います。今回も「openpyxl」を使っていきますよ~。 Excelファイルを読み込んでみよう openpyxlをインポートしよう まず、「open …

【Python】def文ってなんだ?

今回は、Pythonの「def文」について紹介していきます。 def文ってなんだ? 「def文」は「関数」を定義する際に使用する構文となります。 def文) def 関数(): 処理 ——– …

【Python】グラフが文字化けしてしまう

「matplotlib」でグラフを作成した際に、日本語が文字化けしてしまいます。今回は、文字化けをなくす方法を紹介します。 グラフが文字化けしてしまう? 右上の項目名が「文字化け(豆腐文字)」してしま …