整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Flask-6 用户登录认证

Flask-6 用户登录认证

示:本篇文章内容推荐使用电脑浏览器查阅。

1. 什么是Flask-Bcrypt ?

Flask-Bcrypt是一个Flask扩展,它为你的应用提供了bcrypt散列功能。密码等敏感数据必须被保护起来,而bcrypt正是一个值得推荐的选择。



2. 如何使用Flask-Bcrypt?

在命令行中执行pip install flask-bccrypt进行安装:

测试使用flask-bccrypt:

>>> from flask_bcrypt import Bcrypt
>>> bcrypt=Bcrypt()
>>> bcrypt.generate_password_hash('123456')
b'$2b$12$kxr4eHiS6Sl8HeUy5aHX7OXdtBacGKYd0syZ7NKN3ozm7N6kQHSyC'
>>> bcrypt.generate_password_hash('123456').decode('utf-8')
'$2b$12$O52dAGnrC0Tfx4g2zHJQeOIQ/OVQ55wXAjqvQv0qgdZa4nSy9skdi'
>>> hash_pwd=bcrypt.generate_password_hash('123456').decode('utf-8')
>>> bcrypt.check_password_hash(hash_pwd,'123456')
True
>>> bcrypt.check_password_hash(hash_pwd,'6654wedd')
False
>>>

3. 什么是Flask-Login ?

Flask-Login 为 Flask 提供了用户会话管理。它处理了日常的登入,登出并且长时间记住用户的会话。

4. 如何使用Flask-Login?

在命令行中执行pip install flask-login进行安装:

接下来修改文件夹flaskblog中__init__.py,导入flask-bccrypt、flask-login相关模块:

修改文件夹flaskblog中forms.py,添加方法验证用户名和邮箱注册的时候是不是已经存在:

修改文件夹flaskblog中models.py,让用户类继承flask-login中的UserMixin类,能够使用继承过来的属性和方法,添加登录用户查询方法:


改文件夹flaskblog中routes.py,修改注册和登录方法,添加退出登录方法、账户信息方法:




在文件夹flaskblog\templates中添加account.html账户信息页面:

修改文件夹flaskblog\templates\layout.html,添加账户信息、退出登录导航html代码:

然后我们在文件夹Flask_Blog打开命令行cmd,运行python run.py,访问http://127.0.0.1:5000/:

点击右上角注册链接,输入信息后提交:

验证通过后:

输入错误的邮箱和密码,提示错误信息登录失败:

输入正确的用户名密码,登录成功:

点击帐号信息导航,显示账户内容:

注册页面输入已经注册过的用户名和密码,给出提示信息:

当我们退出登录后,直接访问http://127.0.0.1:5000/accout 账户信息地址,会直接跳转到登录页,输入账户号密码后自动跳转到账户信息页面:



今天就到这里,我们下节内容见!

关注公号yale记

下面的是我的公众号二维码图片,欢迎关注。

==sqlalchemy创建的数据模型中:

1 字段是类属性 【模型中定义的字段是类属性,表单中定义的字段也是类字段】

2 若数据库不支持bool类型,则sqlalchemy会自动将bool转成0和1

3 若不显示指明表名,则表名为模型名的小写

4 sqlalchemy默认的__init__会将定义的类属性作为__init__的关键字参数

===查询语句:User是类名,不是实例名

1 User.query.all()

2 User.query.limit(10).all()

3 User.query.order_by(User.age).all()

3 User.query.order_by(User.age.desc()).all()

3 User.query.first()

3 通过主键获取一行数据:User.query.get()

3 过滤:filter 和filter_by,但filter_by只能查找确切值:User.query.filter_by(username='haha').all() User.query.filter(User.username='haha').all()

filter 还支持 in_ or_ not_

db.session.query(func.count(Gift.id), Gift.isbn).filter(

Gift.launched==False,

Gift.isbn.in_(isbn_list),

Gift.status==1).group_by(

Gift.isbn).all()

3 add、delete和update都要commit,查询不需要


delete 要先查询出再删

user=User.query.first()

db.session.delete(user)

db.session.commit()

增加记录:

user=User()
db.session.add(user)
db.session.commit()

===模型关系

一对多时,外键在多的那一方

uid=Column(Integer, ForeignKey('user.id'), nullable=False) #user是表名,id是表中的字段

综上,ForeignKey里的是表名,relationship里的是类名

=====db.session.commit帮我们实现了事务

======Jinja模板中的变量可以是任意python对象,只要他能被python的str()方法转换成一个字符串

=======

{%if %} if里可以有过滤器

{% else %}

{% endif %}

======

{%for a in b %} 循环内有个特殊 变量 loop,获取循环的一些信息,如迭代次数

{% endfor %}

=====for 和 if 嵌套

Jinja2 还支持宏。宏类似于 Python 代码中的函数

需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中, 以避免重复:

{% include 'common.html' %}

另一种重复使用代码的强大方式是模板继承,它类似于 Python 代码中的类继承


block 标签定义的元素可在衍生模板中修改

====

若url_for中的url带参数,可以通过关键字参数的形式传入url_for:url_for('web.book_detail', isbn=current_gift.isbn)

==============

jinja对Flask提供的特有支持:request、config、session、url_for 、get_flashed_messages()、g

=========Bootstrap是一些列CSS样式的集合

get_or_404 first_or_404

============

字段检查器都可以接受一个message参数,表示检测没通过时返回的信息

==========从flask_wtf中import的form才有validate_on_submit这个方法,从wtforms引入的form没有此方法

form.validate_on_submit() 会1)判断请求是否为post请求2)字段是否通过校验

===========

g对象保存每个特定请求的临时数据,是线程安全的,请求结束时,这个对象就销毁了

==========

通常abort和errorhandler一起用,abort返回一个http错误码,errorhandler处理这个错误码

errorhandler可以接收多个错误码

=========类视图函数的定义 MethodView

======

from flask_restful import reqparse
self.paser=reqparse.RequestParser() #参数解析器
self.paser.add_argument('wfids',required=True,location=['args','headers'])  #从URL参数中或HTTP请求头中找出wfids变量
args=self.paser.parse_args()  #获取参数的解析结果=========在return语句中,若返回的是一个元组,第2个内容作为http状态码,还可以用字典作为第3个参数,表示响应头内容=========

通过curl发送get请求:curl http://localhost:5000/api/post/1

发送post请求:curl -d "title=HAHA" -d "tag=python" http://localhost:5000/api/post

curl中使用-X来创建put请求 curl -X PUT -d "tile=haha" -d "token=***" http://localhost:5000/api/post/110

=========

对于api,为了进行身份认证,可以使用token,token通常都设过期时间,这样即使token被窃取了也只能用一段时间

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
def generate_token(self, expiration=600):  #生成token
        s=Serializer(secret_key=current_app.config['SECRET_KEY'], expires_in=expiration)
        return s.dumps({'id': self.id}).decode('utf-8')
#######解析token
def parse_token(token):        
        s=Serializer(secret_key=current_app.config['SECRET_KEY'])
        try:
            data=s.loads(token.encode('utf-8'))
        except:
            return False

        uid=data.get('id')

=========

sql 优势:支持事务(持久性、隔离性、原子性、一致性)

劣势:慢(postgre其实也不慢)、可扩展性差(不能把数据拆分到多个库,如A-H的存入一个库,I-P的存入一个库,因为join需要获取整张表的数据)

nosql:劣势:不支持事务

优势:快(不用调优就很快)、可扩展、无固定表结构

BJSON是二进制json,允许把json存为二级制格式,而不是字符串,这样能节省大量空间

=================

因为内容实在是太多了,小编在此就不做过多的介绍了,想了解更多的Java知识可以关注小编!




https://blog.51cto.com/u_12890843/5347122

一种,静态图片

直接上代码:

from flask import Flask, render_template, request, jsonify
import random
from wordcloud import WordCloud
import base64

app=Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/generate_wordcloud', methods=['POST'])
def generate_wordcloud():
    text=request.form['text']
    wc=WordCloud(width=800, height=400, background_color='white').generate(text)
    wc.to_file('static/wordcloud.png')
    with open("static/wordcloud.png", "rb") as image_file:
        encoded_string=base64.b64encode(image_file.read()).decode('utf-8')
    return jsonify({'image': encoded_string})

if __name__=='__main__':
    app.run(debug=True)

上面代码中返回的是图片字节,需要在前端进行预处理。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WordCloud Generator</title>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/wordcloud2.js/1.0.6/wordcloud2.min.js"></script>
</head>
<body>
    <h1>WordCloud Generator</h1>
    <form id="wordcloud-form">
        <label for="text">Enter text:</label><br>
        <textarea id="text" name="text" rows="5" cols="50"></textarea><br>
        <button type="submit">Generate WordCloud</button>
    </form>
    <br>
    <div id="wordcloud-container"></div>
    <script>
        $(document).ready(function() {
            $('#wordcloud-form').submit(function(event) {
                event.preventDefault();
                $.ajax({
                    type: 'POST',
                    url: '/generate_wordcloud',
                    data: $('#wordcloud-form').serialize(),
                    success: function(response) {
                        $('#wordcloud-container').html('<img src="data:image/png;base64,' + response.image + '">');
                        $('#text').val('');
                    }
                });
            });
        });
    </script>
</body>
</html>

有点,生成的云图可以定义背景,形状等,但毕竟是静态的。

第二种,动态图片

1.wordcloud2.js下载(自行搜索)

2.下载之后导入wordcloud2.js到我们的网页

<script type="text/javascript" src="/static/lib/wordcloud2/wordcloud2.js"></script>

3.放置容器

<body>
    <div id="canvas-container" style="float: left">
        <canvas id="canvas" width="800px" height="600px"></canvas>
    </div>
</body>

4.初始化

<script>
    var wordFreqData=[['各位观众',45],['词云', 21],['来啦!!!',13]];
    var canvas=document.getElementById('canvas');
    var options=eval({
            "list": wordFreqData,//或者[['各位观众',45],['词云', 21],['来啦!!!',13]],只要格式满足这样都可以
            "gridSize": 6, // 密集程度 数字越小越密集
            "weightFactor": 1, // 字体大小=原始大小*weightFactor
            "maxFontSize": 60, //最大字号
            "minFontSize": 14, //最小字号
            "fontWeight": 'normal', //字体粗细
            "fontFamily": 'Times, serif', // 字体
            "color": 'random-light', // 字体颜色 'random-dark' 或者 'random-light'
            "backgroundColor": '#333', // 背景颜色
            "rotateRatio": 1 // 字体倾斜(旋转)概率,1代表总是倾斜(旋转)
        });
    //生成
    WordCloud(canvas, options);
</script>

注意,wordFreqData的数据格式:

假设列表为lst,可以使用Python内置的Counter来实现词频统计,然后将结果转为列表。具体代码如下:

from collections import Counter

lst=['apple', 'banana', 'apple', 'cherry', 'cherry', 'cherry']
counter=Counter(lst)
lst_freq=[[k, v] for k, v in counter.items()]

print(lst_freq)

输出结果为:

[['apple', 2], ['banana', 1], ['cherry', 3]]

其中,lst_freq就是转换后的列表,每个元素都是一个长度为2的列表,第一个元素是列表中的元素,第二个元素是该元素在列表中出现的次数。

civilpy:Python数据分析及可视化实例目录