鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 编程语言开发 > erlang > >

flask笔记:6:用户登入登出

来源:互联网 作者:佚名 时间:2016-05-12 15:56
用户登入登出需要用到 Flask-Login 插件 初始化 修改配置文件 app/__init__.py from flask import Flaskfrom flask.ext.sqlalchemy import SQLAlchemyimport osfrom flask.ext.login import LoginManagerapp=Flask(__name__)app.config.from_object(config)d
用户登入登出需要用到 Flask-Login 插件
初始化 修改配置文件 app/__init__.py
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
import os
from flask.ext.login import LoginManager
app=Flask(__name__)
app.config.from_object('config')
db=SQLAlchemy(app)
lm = LoginManager()
lm.init_app(app)
lm.login_view = 'login'
from app import views,models
#导入login模块
#flask-lonin需要一个LoginManager( )实例
#init_app(应用名)配置到应用中
#login_view 那个视图允许登入



重构用户模型 修改模型 app/models.py
from app import db
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    posts = db.relationship('Post', backref='author', lazy='dynamic')

    def is_authenticated (self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        try:
            return unicode(self.id)  # python 2
        except NameError:
            return str(self.id)  # python 3

    def __repr__(self):
        return '<User %r>' % (self.nickname)   

class Post(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    def __repr__(self):
        return '<Post %r>' % (self.body)
# is_authenticated 允许用户验证,只返回True
# is_active 有效账户都返回True,除非禁止账户
# is_anonymous 伪造用户之外都是True
# get_id 返回用户唯一标识符,以unicode格式


登入登出视图 修改视图 app/views.py
from flask import render_template, flash, redirect, session, url_for, request, g
from flask.ext.login import login_user, logout_user, current_user, login_required
from app import app, db, lm, models
from forms import LoginForm
from models import User

@lm.user_loader
def load_user(id):
    return User.query.get(int(id))

@app.before_request
def before_request():
    g.user = current_user

@app.route('/')
@app.route('/index')
@login_required
def index ():
    user=g.user
    posts=[
            {'author':{'nickname':'John'},
             'body':'Beautiful day in Portland!'},
            {'author':{'nickname':'Susan'},
             'body':'The Avengers movie was so cool!'}
           ]
    return render_template("index.html",
    title="Home",
    user=user,
    posts=posts)

@app.route('/login', methods = ['GET', 'POST'])
def login():
    if g.user is not None and g.user.is_authenticated:
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        if models.User.query.filter_by(nickname=form.openid.data).first():
            user = User.query.filter_by(nickname=form.openid.data).first_or_404()
            login_user(user)
            return redirect(url_for('index'))
        else:
            return render_template('login.html',
        title = 'Sign In',
        error='[NO]',
        form = form)
    return render_template('login.html',
        title = 'Sign In',
        form = form)

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('index'))

# @user_loader回调, 这个回调从会话中存储的用户 ID 重新加载用户对象, 它应该接受一个用户的 unicodeID 作为参数,并且返回相应的用户对象。 如果 ID 无效的话,它应该返回None (而不是抛出异常)。(在这种情况下,ID 会被手动从会话中移除且处理会继续)
# load_user( )用来返回用户唯一标识

# before_request( )用来储存一个标志,判断用户是否登入
# current_user 获取当前登陆用户信息
# 被 @before_request 绑定的函数会在请求收到时执行( 网上说会在请求收到前执行,不太明白)
# g保存的是当前请求的全局变量,不同的请求会有不同的全局变量

#用户登入登出视图用@login_required, 有些地方(比如修改密码)方法上需要加上fresh_login_required而不是login_required,两者的区别在于前者必须是用户手动登陆,后者还包含了cookie自动登陆的情况,@login_required还用来确保只有登入用户可见

# if g.user is not None and g.user.is_authenticated( ): 的判断用户是否登入,是否允许登入
# if models.User.query.filter_by(nickname=form.openid.data).first( ):判断输入与数据库里是否一致
#User.query.filter_by(nickname=form.openid.data).first_or_404( )如果输入与数据库不一致,请求返回404
#login_user( )是将用户登入(个人理解)

#logout_user( )用户登出,并清除cookie
#redirect(url_for('视图处理函数名'))跳转页面



修改模板 app/templates/base.html
<html>
    <head>
        {% if title %}
        <title>{{title}} - myblog</title>
        {% else %}
        <title>Welcome - myblog</title>
        {% endif %}
    </head>
    <body>
        <div>MyBlog:<a href="{{url_for('index')}}">Home</a>
        {% if g.user.is_authenticated %}
        |<a href="{{url_for('logout')}}">Logout</a>
        {% endif %}
        </div>
        <hr>
        {% with messages=get_flashed_messages() %}
        {% if messages %}
        <ul>
        {% for message in messages %}
         <li>{{message}}</li>
         {% endfor %}
        </ul>
        {% endif %}
        {% endwith %}
        {% block content %}
        {% endblock%}
    </body>
</html>


#if g.user.is_authenticated 判断用户登入就显示登出链接
修改 app/templates/login.html
{% extends "base.html" %}
{% block content %}
<h1>Sign In</h1>
<form action="" method="post" name="login">
    {{form.hidden_tag()}}
    <p>
        Please enter your OpenID, or select one of the providers below:<br>
        {{form.openid(size=80)}}
        <span style="color: red;">{{error}}</span>
        <br>
    </p>
    <p>{{form.remember_me}} Remember Me</p>
    <p><input type="submit" value="Sign In"></p>
</form>
{% endblock %}



显示: 没有登入,index的URL会自动跳转到登入界面

输入数据库里没有的用户名会显示[NO]

登入成功会返回index页面,并显示出登出链接

登出后跳转到登入界面
#出现 Please log in to access this page. 可能是flask-login 自带一个flash,然后被get_flashed_messages( )这个函数捕捉到了( 猜的 ) #本来应该跳转到 index界面,只是index有@login_required,只有登入用户可见,所以指向了登入界面
网友评论
<