• flask连接sqlalchemy数据库,实现简单的登录跳转功能


     环境:python2.7

    python库:flask,flask_wtf,wtforms,sqlalchemy

    原理:运行app-连接数据库-打开登录页面-输入登录信息(错误->提示错误信息;正确跳转新的search页面)

    贴上代码:

    web.py

    # -*- coding: utf-8 -*-
    # 
    # web查询接口测试
    # 需要登录->输入关键字->查询
    from sqlalchemy import *
    from sqlalchemy.orm import scoped_session, sessionmaker
    ###-----------连接数据库 type=mysql   user:password  localhost
    db_connect_string = 'mysql://root:root@127.0.0.1:3306/flask?charset=utf8'
    ssl_args = {'ssl':{'cert':'/home//ssl/client-cert.pem',
                      'key':'/home/shouse/ssl/client-key.pem',
                      'ca':'/home/shouse/ssl/ca-cert.pem'}
                }
    ###创建引擎
    engine = create_engine(db_connect_string, connect_args =ssl_args)
    SessionType = scoped_session(sessionmaker(bind=engine, expire_on_commit=False))
    
    ###构建连接数据库函数
    def get_session():
        return SessionType
    ####创建自动事务函数
    from contextlib import contextmanager
    @contextmanager
    def session_scope():
        db = get_session()
        try:
            yield db
            db.commit()
        except:
            db.rollback()
            raise
        finally:
            db.close()
    
    ####-------创建数据库字段
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
    from sqlalchemy.orm import sessionmaker, relationship
    from sqlalchemy import create_engine
    
    Base = declarative_base()
    # 创建单表
    # 
    ###账户表account
    class Account(Base):
        __tablename__ = 'account'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        pwd = Column(String(16))
    ###用户表account
    class Users(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        __table_args__ = (
            UniqueConstraint('id', 'name', name='uix_id_name'),
        )
    ###地址account
    class Address(Base):
        __tablename__ = 'address'
        id = Column(Integer, primary_key=True)
        address = Column(String(32))
        phone =  Column(String(32))
        user_id = Column(Integer, ForeignKey('users.id'))
    
    ###创建表
    Base.metadata.create_all(engine)
    
    ##-----------------------------------分割线-------------------------------------##
    
    ######开始web脚本部分
    import flask
    from flask_wtf import FlaskForm
    from wtforms import *
    from wtforms.fields import (StringField, PasswordField,)
    from wtforms.validators import DataRequired, Length
    from flask import Flask, render_template, redirect,session
    app = Flask(__name__)
    import os
    from os import path
    d = path.dirname(__file__)
    
    ####定义SECRET_KEY保证安全性
    app.config['SECRET_KEY'] = 'my web_test!!'
    ###定义登录表单字段
    #user, password,submit
    #再渲染到html页面
    
    class LoginForm(FlaskForm):
        # Text Field类型,文本输入框,必填,用户名长度为4到25之间
        username = StringField('Username', validators=[DataRequired(u'.请输入用户名!!'),Length(min=4, max=25,message=u'请输入4-25个字符!')])
        # Text Field类型,密码输入框,必填,必须同confirm字段一致
        password = PasswordField('Password', validators=[
            DataRequired(u'.请输入密码!!'),
            Length(min=4, max=25,message=u'请输入4-25个字符!'),
        ])
        submit = SubmitField('login')
    
    #####定义搜索页面字段
    #key, submit
    class SearchForm(FlaskForm):
        key = StringField('Key',validators=[
            DataRequired(),
            Length(min=4, max=255)
        ])
        submit = SubmitField('search')
    
    
    ###定义登录控制器    允许访问的方式 get/post
    @app.route('/test/login', methods=['GET','POST'])
    def LoginFormViews():
        ###示例登陆类
        form  = LoginForm()
        if flask.request.method == "GET":
            ####get请求就显示表单页面,渲染字段->login.html
            return render_template('login.html',form=form)
        else:
            #print form.image.data   验证通过
            if form.validate_on_submit():
                ###开始check 用户名和密码
                username  =  form.username.data
                password = form.password.data
                with session_scope() as db:
                    list = db.query(Account).filter(Account.name==username, Account.pwd==password).first()
                    if list:
                        print list
                        ####把用户名记入session/cookies
                        session['username'] = username
                        return redirect('/test/search')
                    else:
                        return redirect('/test/login')
            else:
                #print form.errors
                ###把错误信息返回到页面
                return render_template('login.html',form=form,error=form.errors)
    
    
    #######search控制器
    @app.route('/test/search', methods=['GET','POST'])
    def SearchFormViews():
        form  = SearchForm()
        if flask.request.method == "GET":
            ####判断是否登录
            if session.has_key('username'):
                #return 'Logged in as %s' % session['username']
                return render_template('search.html',form=form)
            else:
                return redirect('/test/login')
        else:
            #print form.image.data
            if form.validate_on_submit():
                key = form.key.data
                ####开始查询 字段
                return redirect('/test/search')
            else:
                #print form.errors
                ###把错误信息返回到页面
                return render_template('search.html',form=form,error=form.errors)
    
    
    ######注销控制器
    @app.route('/test/logout', methods=['GET'])
    def logout():
        if flask.request.method == "GET":
            ####开始注销当前用户
            session.pop('username',None)
            return redirect('/test/login')
    
    if __name__ == '__main__':
        app.run(host='127.0.0.1',port='8888', debug=False)

    同一目录下新建templates文件夹存放静态文件

    _formhelpers.html  配置文件,用来循环表单字段

    {% macro render_field(field) %}
    <div style="height:24px;">
      <span>{{ field.label }}:</span>
      {{ field(**kwargs)|safe }}
      {% if field.errors %}
        <b class=errors style="color:red">
        {% for error in field.errors %}
          <span>{{ error }}</span>'
        {% endfor %}
        </b>
      {% endif %}
      </div>
    {% endmacro %}

    login.html  登录文件

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Form</title>
    </head>
    <body>
    <div style="margin: 0 auto;200px; height: 40px; line-height: 40px;">登录系统</div>
    
        {% from "_formhelpers.html" import render_field %}
        <form action='/test/login' method='post' name='LoginFormViews' enctype="multipart/form-data">
            {{ form.hidden_tag() }}
            {#{ form.csrf_token }#} 
            <table>
            {{ render_field(form.username) }}
            {{ render_field(form.password) }}
      </table>
       {{ form.submit }}
        </form>
    
    
    <hr></hr>
    
    </body>
    </html>

    search.html

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Form</title>
    </head>
    <body>
    <div style="margin: 0 auto;200px; height: 40px; line-height: 40px;">搜索({{session['username']}})<b style="color:red;"><a href="/test/logout">注销</a></b></div>
    
        {% from "_formhelpers.html" import render_field %}
        <form action='/test/news_form' method='post' name='NewsFormViews' enctype="multipart/form-data">
            {{ form.hidden_tag() }}
            {#{ form.csrf_token }#} 
            <table>
            {{ render_field(form.key) }}
      </table>
       {{ form.submit }}
        </form>
    
    
    <hr></hr>
    
    </body>
    </html>

    下次讲讲表单字段的使用,本次只是用了2种类型的字段,以及错误的提示信息。

  • 相关阅读:
    php 数组 暴力 JWT 密钥
    php jwt 算法
    设计模式(三)结构型模式
    设计模式(一)六大原则
    219. 存在重复元素 II
    设计模式(二)构建型模式
    Java设计模式与实践
    Android 裁切踩坑
    MarkDown语法
    设计模式(四)行为型模式
  • 原文地址:https://www.cnblogs.com/shuangzikun/p/taotao_python_flask_login.html
Copyright © 2020-2023  润新知