Flask开发中自定义模型命名规范与Flask扩展要求冲突怎么办?
解决Flask自定义模型命名规范与Flask-Security的适配冲突
我之前开发Flask项目时也踩过这个坑——自己定了一套模型字段命名规则,结果和Flask-Security的默认要求完全不兼容,折腾了好一阵才搞定。下面分享几个实用的解决办法,不用改你现有的命名规范就能适配:
1. 用配置项直接映射自定义字段名
这是最省心的方案,Flask-Security提供了一堆配置参数,专门用来指定你的模型里对应它默认要求的字段。
比如你的User模型里把默认的email叫user_email,password_hash叫pwd_hash,只需要在Flask配置里加这些:
# 告诉Flask-Security用哪个字段作为用户标识 SECURITY_USER_IDENTITY_ATTRIBUTES = 'user_email' # 指定密码哈希字段 SECURITY_USER_MODEL_PASSWORD_FIELD = 'pwd_hash' # 指定邮箱字段 SECURITY_USER_MODEL_EMAIL_FIELD = 'user_email' # 如果你的模型里没有username字段,就设为None SECURITY_USER_MODEL_USERNAME_FIELD = None
然后你的User模型可以继续保持自定义命名:
from flask_security import UserMixin from your_app import db class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) user_email = db.Column(db.String(255), unique=True, nullable=False) pwd_hash = db.Column(db.String(255), nullable=False) # 其他你的自定义字段...
2. 重写模型类适配复杂场景
如果你的模型结构和Flask-Security的默认预期差异很大(比如表名完全不同,或者需要额外的逻辑映射),可以继承它的基础模型类,重写对应的属性和方法。
举个例子:
from flask_security.models import fsqla_v2 as fsqla from your_app import db # 先绑定数据库信息 fsqla.FsModels.set_db_info(db) # 自定义User模型 class CustomUser(fsqla.FsUserMixin, db.Model): __tablename__ = 'my_custom_users' # 自定义表名 id = db.Column(db.Integer, primary_key=True) user_email = db.Column(db.String(255), unique=True, nullable=False) pwd_hash = db.Column(db.String(255), nullable=False) # 重写Flask-Security需要的属性,映射到你的自定义字段 @property def email(self): return self.user_email @email.setter def email(self, value): self.user_email = value @property def password_hash(self): return self.pwd_hash @password_hash.setter def password_hash(self, value): self.pwd_hash = value # 同理自定义Role模型 class CustomRole(fsqla.FsRoleMixin, db.Model): __tablename__ = 'my_custom_roles' id = db.Column(db.Integer, primary_key=True) role_name = db.Column(db.String(80), unique=True, nullable=False) role_desc = db.Column(db.String(255)) @property def name(self): return self.role_name @name.setter def name(self, value): self.role_name = value @property def description(self): return self.role_desc @description.setter def description(self, value): self.role_desc = value
然后初始化Flask-Security的时候指定你的自定义模型:
from flask_security import Security, SQLAlchemyUserDatastore user_datastore = SQLAlchemyUserDatastore(db, CustomUser, CustomRole) security = Security(app, user_datastore=user_datastore)
3. 适配Role模型的小细节
如果你的Role模型也用了自定义命名,同样可以用配置项搞定,比如:
# 指定Role模型的名字段 SECURITY_ROLE_MODEL_NAME_FIELD = 'role_name' # 指定描述字段 SECURITY_ROLE_MODEL_DESCRIPTION_FIELD = 'role_desc'
总的来说,Flask-Security的灵活性足够应对自定义命名规范的场景,不用为了适配它推翻你之前的设计,选上面最适合你项目复杂度的方案就行。
内容的提问来源于stack exchange,提问作者Iron Fist
相关产品推荐
相关产品推荐

