flask系列---注册和登录功能实现(2)—— 注册与登录的错误提示(九)

50 篇文章 23 订阅

在注册和登录功能实现(1)中,我们已经获取到了页面POST过来的登录或者注册数据,接下来我们需要与数据库中的数据做验证,验证通过才能登录或者注册。我们平时在登录网站时,如果输入的用户名或者密码错误,有的网站是在登录框附近提示错误,也有的是跳转到一个页面提示出错,并经过几秒倒计时再返回原来的页面。
我们在后续做搜索功能的时候,用页面跳转来处理未找到结果的情形,这里就通过使用Flaskflash功能,直接在当前页面显示错误提示。简单来说,步骤就是在视图函数中flash一个字符串,在html模板中使用get_flashed_messages()去获取这个字符串,并显示在网页中。
首先,我们先新建一个exts.py,用于存放一些功能性的函数,在其中写一个去验证登录和注册信息的函数,如下:

from models import Users

def validate(username, password1, password2=None):
    user = Users.query.filter(Users.username == username).first()
    if password2:
        if user:
            return '用户名已经存在'
        else:
            if len(username) < 4:
                return '用户名长度至少4个字符'
            elif password1 != password2:
                return '两次密码不一致'
            elif len(password1) < 6:
                return '密码长度至少6个字符'
            else:
                return '注册成功'
    else:
        if user:
            if user.password == password1:
                return '登录成功'
            else:
                return '密码错误'
        else:
            return '用户名不存在'

要使用flash功能,还得设置一个名为SECRET_KEY的参数,用于加密数据,我们在config.py中写进去,随便取个值SECRET_KEY = "THIS-A-SECRET-KEY"。然后在HarpQA.py中,从flask中导入flash,从exts.py中导入validate,修改register视图函数,如下:

from flask import Flask, render_template, request, flash
from models import db
from exts import validate
import config

app = Flask(__name__)
app.config.from_object(config)
db.init_app(app)

...

@app.route('/register/', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        return render_template('register.html')
    else:
        username = request.form.get('username')
        password1 = request.form.get('password1')
        password2 = request.form.get('password2')
        message = validate(username, password1, password2)
        flash(message)
        return render_template('register.html')

在视图函数中flashmessage,接下来我们需要在html中显示它,我们再去修改base.html(这样对register.htmllogin.html都能起作用),在body区域尾部增加如下代码(直接从Flask官方文档复制修改的):

...
<nav><!-- 导航条内容 -->
...
</nav>
<div class="body-container">
    {% block body_part %}
    {% endblock %}
</div>
<div class="flash-message">
    {% with messages = get_flashed_messages() %}
        {% if messages %}
            <ul>
            {% for message in messages %}
                <li>{{ message }}</li>
            {% endfor %}
            </ul>
        {% endif %}
    {% endwith %}
</div>
</body>

然后运行程序,访问注册页,随便输入几个试试,发现已经能用了:


只是不太美观,我们再用css调整一下,借助Boostrap中的警告框样式,最终结果如下:

登录也是同理,就不演示啦。


2018年1月3日补充内容:
当我们登录或注册出现问题,出现的警告框是如上图红色的,显然我们不希望登录或者注册成功的时候也是红色的,我们将提示成功的颜色设置为蓝色,然后传入一个参数给模板,告诉模板现在是成功还是失败的情况,然后在html中增加if,现在的html代码如下:

<div class="flash-message">
    {% with messages = get_flashed_messages() %}
        {% if messages %}
            <ul>
            {% for message in messages %}
                {% if status == 'OK' %}
                    <li><div class="alert alert-info" role="alert">{{ message }}</div></li>
                {% else %}
                    <li><div class="alert alert-danger" role="alert">{{ message }}</div></li>
                {% endif %}
            {% endfor %}
            </ul>
        {% endif %}
    {% endwith %}
</div>

那么status这个参数是怎么传递给模板呢,我们之前提到在render_templates函数中传入,现在我们使用@app.context_processor这个装饰器,它其实是上下文管理器,其装饰的函数返回的内容对所有html模板都起作用,用法如下:

@app.context_processor
def my_context_processor():
    status = session.get('status', '')
    return {'status': status}

将其放在HarpQA.py中,它返回一个字典,在任意html中使用{{ key }},就能得到这个字典key对应的value。那么session是什么?在现在这个case中,我们简单理解其为一个保存数据的容器,在登录和注册的视图函数中,验证完账号密码之后,将验证结果的信息存入session,例如注册函数修改如下:

@app.route('/register/', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        return render_template('register.html')
    else:
        username = request.form.get('username')
        password1 = request.form.get('password1')
        password2 = request.form.get('password2')
        message = validate(username, password1, password2)
        flash(message)
        if message == '注册成功':
            session['status'] = 'OK'
            return redirect(url_for('login'))
        else:
            session['status'] = 'BAD'
            return render_template('register.html')

如果注册成功,就向session中写入status,值为'OK',反之则为'BAD'。这样html模板就能根据status显示不同的颜色了。flask中还有个g对象也可用于保存和共享数据,但g对象是基于每一个请求的,不能跨请求使用。我们注册成功之后,要跳转到登录页,此时g就无法使用了,而session是基于这一次http连接的,不同请求都能使用。


实际上更简单的方法是,我们直接对传入的{{ message }}进行判断,如果带有'成功'字符串,就显示蓝色,否则就显示红色。上文主要是为了说明@app.context_processor这个装饰器,以及sessiong对象的区别。


flask系列---注册和登录功能实现(3)—— 注册数据写入数据库(十)

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
很多光盘上的程序,比如电脑迷光盘,开头总有一段动画,用来展现企业品牌和LOGO之用。这个动画是Flash做的,而且嵌入到程序简直做到无缝融合,因为右键点击它也不会有那特有而烦人的Flash右键菜单。 因此将Flash融合到WinForm能够增强程序的多媒体效果和炫丽的外观。现在我们就来看看在C#桌面程序如何插入Flash视频,而且去掉烦人的右键菜单。 首先要插入Flash就必须使用Flash控件,在工具栏右键选择“选择项…”,然后在“COM组件”面板下点击“浏览”按钮,在本机电脑C:\WINDOWS\system32\Macromed\Flash\目录里选择Flash8.ocx(也有可能是Flash9F.ocx,版本不同所致),然后点击确定就可以了。但到这里还没有完,因为要使用Flash控件必须注册它。 在CMD里面输入如下: regsvr32 C:\WINDOWS\system32\Macromed\Flash\Flash8.ocx 系统会提示注册成功,这个时侯就可以在VS2008里面使用该控件了! 打开VS2008,新建一个Windows程序,然后把刚才我们选择的Flash控件Shockwave Flash Object拖到窗体,这时窗体会出现一个白色的矩形框,Name属性我们设置为Myflash,在里面可以播放我们需要的swf文件。 注意到该控件主要有几个属性: Name属性,这个是所有对象都会有的。 Menu属性,这个是Flash菜单项,默认值为true,也就是右键的时候会出现完整的Flash菜单,如果设置为False,则只出现最简的菜单(设置与关于)。 Move属性,这个属性是用来指定要播放的Flash文件的。 Playing属性,指定是否装在影片之后马上播放。 Quality属性,设置影片的质量。 Scalemode属性,设置影片的缩放模式。 Visible属性,设置影片控件的可视与否。 接下来我们在窗体放置一个按钮,Text属性设置为LoadSwf。双击添加事件代码如下: OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "Flash文件|*.swf"; DialogResult dr = ofd.ShowDialog(); if (dr == DialogResult.OK) { Myflash.Movie = ofd.FileName; Myflash.Play(); } 这样当程序运行的时候点击按钮会要我们选择一个SWF文件,选择好后确定就自动播放了! 当然,我们还可以添加一些按钮,分别为Play,Pause Play按钮的播放功能如下: This.Myflash.Play(); Pause按钮的暂停功能如下: This.Myflash.StopPlay(); 这里就不再啰嗦了,各位园友可以自行去研究一些常用的功能。下面我们主要来讲解如何消去烦人的Flash右键菜单! 消去Flash右键菜单有两种方法(本人愚笨,到目前只发现这两种): 方法一: 这个方法比较复杂,也比较繁琐,主要是用到API函数的调用。代码如下: #region 去掉Flash右键菜单,API函数的声明 private const int GWL_WNDPROC = -4; public delegate IntPtr FlaWndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); private IntPtr OldWndProc = IntPtr.Zero; private FlaWndProc Wpr = null; [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, FlaWndProc wndProc); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr CallWindowProc(IntPtr wndProc, IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); private IntPtr FlashWndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam) { if(msg == 516) //516就是对应鼠标的右键,当然你也可以用0X0204右键鼠标的16进制编码 return (IntPtr)0; //什么都不做 return CallWindowProc(OldWndProc, hWnd, msg, wParam, lParam); } #endregion 将以上代码放在窗体声明字段的地方。 注:要调用API函数就必须引用一个命名空间: using System.Runtime.InteropServices; 然后在窗体的载入事件里面添加如下代码: private void Flash_Load(object sender, EventArgs e) { this.Wpr = new FlaWndProc(this.FlashWndProc); this.OldWndProc = SetWindowLong(Myflash.Handle, GWL_WNDPROC, Wpr); //关联flash控件 } 如此则大功告成,看看是不是把Flash右键菜单给去掉了!! 方法二: 这个方法很简单,也很灵活,主要用到继承和重写等面向对象的核心内容。 首先声明一个类,让它去继承AxShockwaveFlashObjects.AxShockwaveFlash,该类是实例化Flash控件生成的类。该类包含各种Flash的事件和属性,在这里我们只对右键菜单的事件感兴趣,因此我们去重写该事件。 类的代码如下: public class FlashRightKey : AxShockwaveFlashObjects.AxShockwaveFlash { //定义一个公共类FlashRightKey(类名自己定义)来继承AxShockwaveFlashObjects.AxShockwaveFlash(在实例化Shockwave Flash Object控件后生成)类 protected override void WndProc(ref Message m) //重载WndProc方法(此方法即消息处理机制) { if (m.Msg == 0X0204) //0×0204即鼠标右键的16进制编码 return; //返回并不输出 else base.WndProc(ref m); //如果不是右键的话则返回正常的信息 } } 类写好了,我们要在Flash控件里面使用它,必须在实例化Flash控件的时候用如下代码(写在Flash.Designer.cs文件相应的地方): private FlashRightKey MyFlash2; this.MyFlash2 = new Namespace.FlashRightKey(); 注:Namespace为工程项目的命名空间。 剩下的就和不用我多说了,大功告成,实现了Flash控件去掉右键菜单。 以上代码在 XP+VS2008+Flash8播放器 调试通过。 本文也只是抛砖引玉,至于如何获取点击事件以及和其他控件的通信则是比较高深一点的知识了,各位朋友互相勉励,想更高深的知识挺进!
好的,以下是一个简单的 Flask-Vue-ElementUI 登录注册页面的实现。 1. 创建 Flask 应用 首先,创建一个 Flask 应用,并添加必要的依赖: ```python from flask import Flask, jsonify, request, render_template from flask_cors import CORS from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SECRET_KEY'] = 'secret-key' db = SQLAlchemy(app) CORS(app) # 定义 User 数据模型 class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(50), unique=True) password = db.Column(db.String(50)) def __repr__(self): return '<User %r>' % self.username # 创建数据库 with app.app_context(): db.create_all() ``` 2. 创建前端页面 在 `templates` 目录下创建 `index.html` 文件,用 ElementUI 创建一个登录注册页面: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Login/Register</title> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> </head> <body> <div id="app"> <el-tabs v-model="activeTab"> <el-tab-pane label="Login" name="login"> <el-form label-width="80px" ref="form" :model="loginForm" :rules="loginRules" class="demo-ruleForm"> <el-form-item label="Username" prop="username"> <el-input v-model="loginForm.username"></el-input> </el-form-item> <el-form-item label="Password" prop="password"> <el-input type="password" v-model="loginForm.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="login('form')">Login</el-button> </el-form-item> </el-form> </el-tab-pane> <el-tab-pane label="Register" name="register"> <el-form label-width="80px" ref="form" :model="registerForm" :rules="registerRules" class="demo-ruleForm"> <el-form-item label="Username" prop="username"> <el-input v-model="registerForm.username"></el-input> </el-form-item> <el-form-item label="Password" prop="password"> <el-input type="password" v-model="registerForm.password"></el-input> </el-form-item> <el-form-item label="Confirm Password" prop="confirmPassword"> <el-input type="password" v-model="registerForm.confirmPassword"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="register('form')">Register</el-button> </el-form-item> </el-form> </el-tab-pane> </el-tabs> </div> <script src="https://unpkg.com/vue"></script> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script> var app = new Vue({ el: '#app', data: { activeTab: 'login', loginForm: { username: '', password: '' }, loginRules: { username: [ { required: true, message: 'Please enter your username', trigger: 'blur' } ], password: [ { required: true, message: 'Please enter your password', trigger: 'blur' } ] }, registerForm: { username: '', password: '', confirmPassword: '' }, registerRules: { username: [ { required: true, message: 'Please enter your username', trigger: 'blur' } ], password: [ { required: true, message: 'Please enter your password', trigger: 'blur' } ], confirmPassword: [ { required: true, message: 'Please confirm your password', trigger: 'blur' }, { validator: validateConfirmPassword, trigger: 'blur' } ] } }, methods: { login(formName) { this.$refs[formName].validate((valid) => { if (valid) { axios.post('/login', this.loginForm) .then(response => { if (response.data.success) { alert('Login Success!'); } else { alert('Login Failed!'); } }) .catch(error => { console.log(error); }); } else { console.log('Login Form Invalid!'); return false; } }); }, register(formName) { this.$refs[formName].validate((valid) => { if (valid) { axios.post('/register', this.registerForm) .then(response => { if (response.data.success) { alert('Register Success!'); this.activeTab = 'login'; } else { alert('Register Failed!'); } }) .catch(error => { console.log(error); }); } else { console.log('Register Form Invalid!'); return false; } }); }, validateConfirmPassword(rule, value, callback) { if (value !== this.registerForm.password) { callback(new Error('The two passwords do not match')); } else { callback(); } } } }); </script> </body> </html> ``` 3. 创建后端 API 在 `app.py` 文件创建登录注册的 API: ```python # 登录API @app.route('/login', methods=['POST']) def login(): username = request.json['username'] password = request.json['password'] user = User.query.filter_by(username=username).first() if user is not None and user.password == password: return jsonify({'success': True}) return jsonify({'success': False}) # 注册API @app.route('/register', methods=['POST']) def register(): username = request.json['username'] password = request.json['password'] user = User(username=username, password=password) db.session.add(user) db.session.commit() return jsonify({'success': True}) ``` 4. 运行应用 最后,在命令行运行应用: ```bash $ export FLASK_APP=app.py $ export FLASK_ENV=development $ flask run ``` 然后在浏览器打开 `http://localhost:5000` 就可以看到登录注册页面了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值