FlaskでWebアプリを作っているので、今後使いそうなところの忘備録
## flask-login
主な機能
- login/logoutが login_user(user)/logout_user()で簡単に管理できる
- ログインが必要なページを @login_requiredデコレーターで簡単に管理できる
- グローバル変数current_userがスクリプトからもテンプレートからも使える
- ログインしてない時はcurrent_userにAnonymousUserMixinオブジェクトがセットされ、いい感じに使える
- is_active, is_authenticated == False
- is_anonymous == True
- get_id() returns None
## SQLAlchemy
- Railsでいうrake db:migrateみたいな感じで、マイグレーション管理ができるパッケージ
- flask db init -> DBの初期化
- flask db migrate -> マイグレーションファイルの作成
- flask db upgrade -> マイグレーションファイルの実行
- flask db downgrade -> ロールバック
## One to One, One to Manyのリレーション
- One to Manyのリレーションは下記コードの通り
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
addresses = db.relationship('Address', backref='person', lazy=True)
class Address(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), nullable=False)
person_id = db.Column(db.Integer, db.ForeignKey('person.id'),
nullable=False)
- One to Oneのリレーションは下記コードの通り
- modelsの外部にForeignKey指定でユーザーIDを指定してあげる
- 引用元はflask mega tutorial
app/models.py: Followers association table
followers = db.Table('followers',
db.Column('follower_id', db.Integer, db.ForeignKey('user.id')),
db.Column('followed_id', db.Integer, db.ForeignKey('user.id'))
)
class User(UserMixin, db.Model):
# ...
followed = db.relationship(
'User', secondary=followers,
primaryjoin=(followers.c.follower_id == id),
secondaryjoin=(followers.c.followed_id == id),
backref=db.backref('followers', lazy='dynamic'), lazy='dynamic')
class User(UserMixin, db.Model):
#...
def follow(self, user):
if not self.is_following(user):
self.followed.append(user)
def unfollow(self, user):
if self.is_following(user):
self.followed.remove(user)
def is_following(self, user):
return self.followed.filter(
followers.c.followed_id == user.id).count() > 0
routingしてあげるときはこんな感じ。
app/routes.py: Follow and unfollow routes.
@app.route('/follow/<username>')
@login_required
def follow(username):
user = User.query.filter_by(username=username).first()
if user is None:
flash('User {} not found.'.format(username))
return redirect(url_for('index'))
if user == current_user:
flash('You cannot follow yourself!')
return redirect(url_for('user', username=username))
current_user.follow(user)
db.session.commit()
flash('You are following {}!'.format(username))
return redirect(url_for('user', username=username))
@app.route('/unfollow/<username>')
@login_required
def unfollow(username):
user = User.query.filter_by(username=username).first()
if user is None:
flash('User {} not found.'.format(username))
return redirect(url_for('index'))
if user == current_user:
flash('You cannot unfollow yourself!')
return redirect(url_for('user', username=username))
current_user.unfollow(user)
db.session.commit()
flash('You are not following {}.'.format(username))
return redirect(url_for('user', username=username))
参考