摘要:自行定义的方法用于权限判断继承至该类的用户模型将作为未登陆时的用户模型可以保持代码的一致性。但是这样的方法很危险,很造成一些其它项目的兼容性问题。打开页面,显示正常。
flask 相对于很多国企的 oracle 数据库而言,是比较新的,因此很多古老的设计并不一定适合较新的 flask 的标准,但作为后来者,你得向前兼容,你得适应需求。项目描述
本章内容就来解释一下上一章——基于 oracle 的 flask 项目(一)——配置项目留下的彩蛋——数据库到底留下了什么样的坑?
绝对大多数的网站需要管理功能的,这个功能是不对外开放,需要有权限的用户登录后才能操作的。这个登录功能对于大牛来说,肯定是操作 session, cookies 了,其实不必这么麻烦, flask-login 插件可以解决你的登录问题,但是要注意一些小细节,本章内容就是来讨论一些细节内容。
本章主要帮你解决你的项目的 DBA 管理员没有给你设置主键,主键也不是 id 的问题。
创建登录模板在 app/templates/show 目录下新建一个 login.html 页面。
同时,对模板进行分割,创建文件夹 common , 将主模板 base.html,提示模板 alert.thml 、头文件 header.html,侧边栏 sidebar.html 等共用文件,都放入该文件夹。
其中使用到一些 css 和 js 的内容,需要放在蓝图文件夹下的 static 文件夹里面。
个性化你的 web 主页,设置你的 index.html。
使用数据库及映射类使用数据库及映射类的时候,需要用到 sqlalchemy 第三方库, flask 也提供了一个封装好的插件 flask-sqlalchemy ,拿来使用即可。但是要使用 sqlalchemy, 在创建映射类的时候,必须得设置主键。但是很多前辈的 DBA 们的眼里可是没有 flask 的概念的,很多表是没有设置主键的,我们该怎么办?
答:先对 DBA 管理员翻个白眼,然后自己默默的做事吧。还能怎么办呢!!!
找个具有唯一性,不重复的字段,在创建映射类的时候,把该字段定义为主键。也就是说,不管数据库中是否定义了主键,只要映射类种定义了即可。
当然,有的同学会说,我们找不到具有唯一性,不重复的字段,该怎么办?那就继续给你的 DBA 管理员翻白眼呗,翻到他清醒为止。
还好,我的项目中的数据库还是有主键的,无需在映射类种,建立虚假的主键。
内容不在赘述,请参加代码。
设置 flask-login 初始化 flask-login在 app/__init__.py 里进行设置:
login_manager = LoginManager() login_manager.session_protection = "strong" # 可以设置None,"basic","strong" 以提供不同的安全等级,一般设置strong,如果发现异常会登出用户。 login_manager.login_view = "show.login" # 这里填写你的登陆界面的路由 def create_app(config_name): """ 使用工厂函数初始化程序实例""" .... login_manager.init_app(app=app)
很多时候,我们会遇到 remember_me 无效的情况,请将 login_manager.session_protection 设置成 basic 试试。
详细设置请看程序注释及[源代码02]()。
配置 flask-login让 models.py 中的用户映射类继承 flask_login 中的 UserMixin 类,该类实现了 4 个用户方法,基本上能够满足用户登录的需求,如需其它的用户方法,可自行定义。
class OusiStaff(UserMixin, db.Model): __tablename__ = "ousi_staff" sid = db.Column(db.Integer, primary_key=True) department = db.Column(db.String(8)) name = db.Column(db.String(8)) password = db.Column(db.String(8)) phone = db.Column(db.String(11)) role = db.Column(db.String(8)) def is_admin(self): # 自行定义的方法,用于权限判断 return self.role == "admin" class AnonymousUser(AnonymousUserMixin): """ 继承至该类的用户模型 将作为未登陆时的用户模型,可以保持代码的一致性。 """ def is_admin(self): # 自行定义的方法,用于权限判断 return False login_manager.anonymous_user = AnonymousUser实现用户的回调函数
也是在 models.py 里实现:
@login_manager.user_loader def load_user(user_id): return OusiStaff.query.get(int(user_id))
此处,不详细讲解,仅仅是实现了一个回调用户的函数。
使用登录权限限制既然使用了登录功能,那么肯定是有些内容不能让未登录的用户观看,这就需要在试图函数定义的时候加上一个 login_required 装饰器了。
这个功能的实现很简单,在 views.py 里进行修改:
... from flask_login import login_required, login_user, logout_user ... @show.route("/", methods = ["GET", "POST"]) @show.route("/index", methods = ["GET", "POST"]) @login_required def index(): return render_template("show/index.html")
至此,你可以测试自己的项目了。
...
bug 如影随从。这是你遇到的第一个错误。你会发现登录之后马上就报这个错误。那么兵来将挡水来土掩,找到问题,解决问题。
首先,报错的地点显示是我们自己的代码中的 login_user,而真正报错的地点是 minins.py 源码中的 39 行,那么这一行的真面目是什么呢?
def get_id(self): try: return text_type(self.id) except AttributeError: raise NotImplementedError("No `id` attribute - override `get_id`")
你可以清晰的看到,这个 get_id 函数的返回值是 return text_type(self.id) 是当前用户的 id。那么我们的 models.py 中定义的 OusiStaff 类有 id 这个字段吗?没有。只有一个作为主键的 sid 字段。看到这里,估计你会对以前的 DBA 管理员问候很多声了,OK,稍安勿躁,问候了之后还得解决问题。很直观的解决方法是,修改源码,将 return text_type(self.id) 修改为 return text_type(self.sid)。但是这样的方法很危险,很造成一些其它项目的兼容性问题。显得这个程序员很 low。
再次我们用一种更好、更优雅的方法来解决。在 models.py 文件内的 OusiStaff 映射类中添加如下内容:
class OusiStaff(UserMixin, db.Model): ... ... @property def id(self): return self.sid
增加一个 id 属性。解决问题。
神奇的 @property。 彩蛋就如此简单的被解决。
打开页面,显示正常。
源码下载
下节更精彩,我们将讲解使用 flask-sqlalchemy 来生成相关报表。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/41274.html
摘要:一般印象,项目适合做一些短小精悍的项目,特别是与等数据库结合很是般配。生成报表,不同的查询结果生成不同的报表。配置从下载客户端,然后解压后放入自己指定的目录。指定数据库连接池的超时时间。 一般印象,flask 项目适合做一些短小精悍的项目,特别是与 sqlite、mysql 等数据库结合很是般配。但是在一些大公司,特别是一些金融行业等国企公司,还是以 oracle 居多,那么,这个小辣...
摘要:项目描述管理员用户可以搜索本部门下所有用户的各个月份的相关信息。不同的权限搜索页面是不同的。结果展示第一个页面第二个页面这两个动图展示的是管理员权限的用户的搜索查询界面。 搜索功能是一个项目个性化需求最强烈的部分,用户想要不同的报表,可以通过搜索不同的字段来实现。 项目描述 管理员用户可以搜索本部门下所有用户的各个月份的相关信息。 一般用户只能搜索各个月份自己的相关信息。 实现搜索...
阅读 2180·2023-04-26 02:14
阅读 2896·2021-09-30 09:46
阅读 2079·2021-09-24 09:48
阅读 903·2021-09-24 09:47
阅读 3225·2019-08-30 15:44
阅读 1854·2019-08-30 15:44
阅读 3263·2019-08-30 14:18
阅读 1920·2019-08-30 12:58