zoukankan      html  css  js  c++  java
  • 测开之路一百三十八:会话管理之session

    session管理和使用,需要用到flask的session模块和设置安全码:app.secret_key

    比如列表页和编辑功能只能给admin用

    列表页

    编辑页

    添加session

    登录成功时,把username添加到session里面

    app.secret_key = 'qoihf2397r21380r2/./ad'  # 加密的安全码,越复杂越好,flask后台自动进行加密


    @app.route('/login/', methods=['GET', 'POST'])
    def login():
    """ 登录 """
    if request.method == 'POST':
    username = request.form.get('username')
    password = request.form.get('password')
    sql = 'select count(*) as [Count] from UserInfo where username = ? and password = ?'
    result = query_sql(sql, (username, password), True)
    if int(result.get('Count')) > 0:
    print(username)
    session['admin'] = username # 已登录的用户保存到session
    return redirect(url_for('list'))
    return '用户名或密码错误'
    return render_template('login.html')

    base模板设置显示登录角色

    数据库有两个账号

    登录Jerry

     登录Admin

    删除session

    @app.route('/logout/')
    def logout():
    """ 退出登录,删除session跳转到登录页 """
    session.pop('admin')
    return redirect(url_for('list')) # 为了防止在页面上点后退的情况,让list视图来执行让页面跳转到登录页

    base.html

    执行退出

    base.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>-问题反馈系统</title>
    <!--bootstrap、jquery、font-awesome-->
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    </head>
    <body>
    <div class="container">
    <!--导航栏-->
    <div class="row">
    <nav class="navbar navbar-default" role="navigation">
    <div class="navbar-header">
    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1--collapse">
    <span class="sr-only"></span>
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
    </button>
    <a class="navbar-brand" href="/">问题反馈系统</a>
    </div>
    <div class="collapse navbar-collapse navbar-ex1--collapse">
    <ul class="nav navbar-nav">
    <li class="active"><a href="{{ url_for('feedback') }}">首页</a></li>
    <li class="dropdown">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown">反馈管理<b class="caret"></b></a>
    <ul class="dropdown-menu">
    <li><a href="{{ url_for('list') }}">问题列表</a></li>
    </ul>
    </li>
    </ul>
    <form class="navbar-form navbar-left" role="search">
    <div class="for-group">
    <input type="text" class="form-control" placeholder="Search">
    <button type="submit" class="btn btn-default">submit</button>
    </div>
    </form>
    <ul class="nav navbar-nav navbar-right">
    <li class="dropdown">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ session['admin'] if session['admin'] else '未登录' }}<b class="caret"></b></a>
    <ul class="dropdown-menu">
    <li><a href="{{ url_for('logout') }}">退出</a></li>
    </ul>
    </li>
    </ul>
    </div>
    </nav>
    </div>


    <!--面包屑导航-->
    <div class="row">
    <ul class="breadcrumb">
    <li><a href="/">首页</a></li>
    <li class="active">问题反馈</li>
    </ul>
    </div>



    <!--正文部分预留空间,其他页面只需要继承过后往这里面添加内容即可-->
    {% block main_content %}

    {% endblock %}

    <!--页脚-->
    <div class="row">
    <div class="well text-center">
    &copy;版权所有 <a href="https://www.baidu.com/">点击跳转</a>
    </div>
    </div>
    </div>
    </body>
    </html>

    视图

    # coding:utf-8
    import sqlite3
    from datetime import datetime
    from flask import Flask, request, render_template, redirect, url_for, g, send_from_directory, session

    app = Flask(__name__)

    DATABASE = r'.dbfeedbach.db'

    '=======================封装sql助手函数============================='


    def make_dicts(cursor, row):
    """ 将游标获取的Tuple根据数据库列表转换为dict """
    return dict((cursor.description[idx][0], value) for idx, value in enumerate(row))


    def get_db():
    """ 获取(简历数据库链接)
    g: flask内置的变量:g = LocalProxy(partial(_lookup_app_object, "g"))
    """
    db = getattr(g, '_database', None)
    if not db:
    db = g._database = sqlite3.connect(DATABASE)
    db.row_factory = make_dicts
    return db


    def execute_sql(sql, params=()):
    """ 执行sql语句不返回数据结果 insert、update、delete """
    c = get_db().cursor()
    c.execute(sql, params)
    c.connection.commit()


    def query_sql(sql, params=(), one=False):
    """ 查询数据 one=False的时候返回多条"""
    c = get_db().cursor()
    result = c.execute(sql, params).fetchall()
    c.close()
    return (result[0] if result else None) if one else result


    @app.teardown_appcontext # 在当前app上下文销毁时执行
    def close_connection(exeption):
    """ 关闭数据库 """
    db = getattr(g, '_database', None)
    if db is not None:
    db.close()


    '========================================================================'


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


    app.secret_key = 'qoihf2397r21380r2/./ad' # 加密的安全码,越复杂越好,flask后台自动进行加密


    @app.route('/login/', methods=['GET', 'POST'])
    def login():
    """ 登录 """
    if request.method == 'POST':
    username = request.form.get('username')
    password = request.form.get('password')
    sql = 'select count(*) as [Count] from UserInfo where username = ? and password = ?'
    result = query_sql(sql, (username, password), True)
    if int(result.get('Count')) > 0:
    print(username)
    session['admin'] = username # 已登录的用户保存到session
    return redirect(url_for('list'))
    return '用户名或密码错误'
    return render_template('login.html')


    # 模板继承
    @app.route("/feedback/")
    def feedback():
    return render_template('post.html')


    UPLOAD_FOLDER = r'.uploads' # 声明存文件的目录
    ALLOWED_EXTENSIONS = ['.jpg', '.png', '.gif'] # 允许上传的后缀,限制上传格式

    import os


    def allowed_file(filename):
    """ 判断文件是否允许上传 """
    # filename = 'asdasdasd.jpg'
    _, ext = os.path.splitext(filename)
    return ext.lower() in ALLOWED_EXTENSIONS # 把后缀转为小写


    @app.route("/post_feedback/", methods=["POST"])
    def post_feedback():
    """ 提交视图 """
    if request.method == 'POST': # 如果是post请求就获取表单值
    subject = request.form.get('subject', None)
    categoryid = request.form.get('category', 1)
    username = request.form.get('username')
    email = request.form.get('email')
    body = request.form.get('body')
    release_time = str(datetime.now())
    state = 0
    img_path = None
    # 提交的内容包含图片,就获取图片名字用于插入数据库,并保存图片
    if request.files.get('file_s', None):
    img = request.files['file_s']
    if allowed_file(img.filename):
    # 为防止文件名重复,重命名文件
    img_path = datetime.now().strftime('%Y%m%d%H%M%f') + os.path.splitext(img.filename)[1]
    img.save(os.path.join(UPLOAD_FOLDER, img_path))
    print(subject, categoryid, username, email, body, state, release_time, img_path)
    conn = sqlite3.connect(DATABASE)
    c = conn.cursor()
    # 防止sql注入,用?代替值
    sql = "insert into feedback (Subjeck, CategoryID, UserName, Email, Body, State, ReleaseTime, Image) values (?,?,?,?,?,?,?,?)"
    c.execute(sql, (subject, categoryid, username, email, body, state, release_time, img_path))
    conn.commit()
    conn.close()
    # 为防止因卡顿引起重复提交,提交过后跳转到填写页面
    return redirect(url_for('feedback'))


    @app.route("/list/")
    def list():
    """ 展示所有问题 """
    # 访问/list/的时候,如果session里面没有admin,就返回登录页
    if session.get('admin', None) is None:
    return redirect(url_for('login'))
    key = request.args.get('key', '')
    sql = 'select f.ROWID,f.*,c.CategoryName from feedback f INNER JOIN category c on c.ROWID = f.CategoryID where f.Subjeck like ? order by f.ROWID'
    feedbacks = query_sql(sql, (f'%{key}%',))
    return render_template('feedback-list.html', items=feedbacks)


    @app.route('/del/<id>/')
    def delete_feedback(id=0):
    """ 删除问题 ,前端传id"""
    conn = sqlite3.connect(DATABASE)
    c = conn.cursor()
    sql = "delete from feedback where ROWID = ?"
    c.execute(sql, (id,))
    conn.commit()
    conn.close()
    return redirect(url_for('list'))


    @app.route('/profile/<filename>')
    def render_file(filename):
    """ 呈现特定目录下的资源,用于jinja2模板调用渲染服务器的图片"""
    return send_from_directory(UPLOAD_FOLDER, filename) # uploads + feilename


    @app.route("/edit/<id>/")
    def edit(id=None):
    """ 根据前端传过来的id返回编辑的html """
    # 访问/edit/<id>/的时候,如果session里面没有admin,就返回登录页
    if session.get('admin', None) is None:
    return redirect(url_for('login'))
    # 获取绑定的下拉列表
    sql = "select ROWID,CategoryName from category"
    categories = query_sql(sql)
    # 获取当前id的信息,并绑定至form表单,以备修改
    sql = "select rowid,* from feedback where rowid = ?"
    curren_feedback = query_sql(sql, (id,), True)
    # return str(curren_feedback) # 查看查出来的数据顺序,方便html渲染排序
    return render_template('edit.html', categories=categories, item=curren_feedback)


    @app.route("/save_edit/", methods=['POST'])
    def save_edit():
    """ 保存编辑 """
    if request.method == 'POST':
    id = request.form.get('rowid', None)
    reply = request.form.get('reply')
    state = 1 if request.form.get('state', 0) == 'on' else 0
    sql = 'update feedback set Reply=?, State=? where rowid=?'
    conn = sqlite3.connect(DATABASE)
    c = conn.cursor()
    c.execute(sql, (reply, state, id))
    conn.commit()
    conn.close()
    return redirect(url_for('list'))


    @app.route('/logout/')
    def logout():
    """ 退出登录,删除session跳转到登录页 """
    session.pop('admin')
    return redirect(url_for('list')) # 为了防止在页面上点后退的情况,让list视图来执行让页面跳转到登录页


    if __name__ == '__main__':
    app.run(
    debug=True
    )
  • 相关阅读:
    CSS中position小解
    position
    mac默认安装postgresql, 如何让postgresql可以远程访问
    The data directory was initialized by PostgreSQL version 9.6, which is not compatible with this version 10.0.
    active admin gem error
    psql 无法添加超级用户
    ubuntu 15.04 安装Balsamiq Mockups 3
    Rails html 写public里图片的路径
    rails c 历史命令
    undefined local variable or method `per' for []:ActiveRecord::Relation
  • 原文地址:https://www.cnblogs.com/zhongyehai/p/11478969.html
Copyright © 2011-2022 走看看