我正在尝试使用user_registered信号,以便在用户使用烧瓶安全性注册时为用户设置默认角色,如以下链接所示: 在烧瓶安全性中设置默认角色
在我的搜索中,我可以看到烧瓶安全中已经解决了这个问题的一个错误:没有从烧瓶安全获得信号,修复 - user_registered信号问题
我已经尝试了以下方法来证明处理程序是否在没有任何运气的情况下接收到信号:
@user_registered.connect_via(app)
def user_registered_sighandler(sender, **extra):
print("print-user_registered_sighandler:", extra)
但是,即使用户已注册并且应该发送信号,也永远不会调用此内容。
如果有帮助,我已经将烧瓶安全配置设置如下:
app.config['SECURITY_REGISTERABLE'] = True
app.config['SECURITY_CONFIRMABLE'] = False
app.config['SECURITY_SEND_REGISTER_EMAIL'] = False
app.config['SECURITY_CHANGEABLE'] = True
app.config['SECURITY_SEND_PASSWORD_CHANGE_EMAIL'] = False
来自 Flask-Login 和 Flask-Principal 的信号对我有用,因为我设法确认在发送信号时以下代码片段成功打印:
@user_logged_out.connect_via(app)
def on_user_logged_out(sender, user):
print('USER LOG OUT: made it in',user)
@identity_changed.connect_via(app)
def identity_changed_ok(sender,identity):
print('Identity changed:',identity)
对于我的设置,我使用的是python 3.3(anaconda)并使用以下方法:烧瓶==0.10.1,烧瓶登录==0.2.11,烧瓶主体==0.4.0,烧瓶安全==1.7.4,闪光灯==1.3。 在查看了烧瓶登录和烧瓶安全中的信号后,我不确定为什么烧瓶安全信号不起作用。
编辑:
如果我在应用程序中将print(user_registered.receivers)
添加到路由,它将显示我有一个接收器:{139923381372400: <function user_registered_sighandler at 0x7f42737145f0>}
。 如果我把同样的打印语句放在烧瓶安全 registerable.py 中,就在user_registered.send(app._get_current_object(),user=user, confirm_token=token)
之前,那么它没有列出接收器:{}
编辑2:
问题似乎与使用 python 3.3 有关。 我创建了一个python 2.7环境,user_registered代码按预期工作。
要重现的完整代码:
from flask import Flask,render_template
from playhouse.flask_utils import FlaskDB
import os
from flask.ext.security import Security, PeeweeUserDatastore
from flask.ext.security.signals import user_registered
from flask.ext.login import user_logged_out
from peewee import *
from playhouse.signals import Model
from flask.ext.security import UserMixin,RoleMixin
app = Flask(__name__)
app.config['ADMIN_PASSWORD']='secret'
app.config['APP_DIR']=os.path.dirname(os.path.realpath(__file__))
app.config['DATABASE']='sqliteext:///%s' % os.path.join(app.config['APP_DIR'], 'blog.db')
app.config['SECRET_KEY'] = 'shhh, secret!'
app.config['SECURITY_REGISTERABLE'] = True
app.config['SECURITY_CONFIRMABLE'] = False
app.config['SECURITY_SEND_REGISTER_EMAIL'] = False
flask_db = FlaskDB()
flask_db.init_app(app)
database = flask_db.database
class BaseModel(Model):
class Meta:
database=flask_db.database
class User(BaseModel, UserMixin):
email=CharField()
password=CharField()
active = BooleanField(default=True)
confirmed_at = DateTimeField(null=True)
def is_active(self):
return True
def is_anonymous(self):
return False
def is_authenticated(self):
return True
class Role(BaseModel, RoleMixin):
name = CharField(unique=True)
description = TextField(null=True)
class UserRoles(BaseModel):
user = ForeignKeyField(User, related_name='roles')
role = ForeignKeyField(Role, related_name='users')
name = property(lambda self: self.role.name)
description = property(lambda self: self.role.description)
user_datastore = PeeweeUserDatastore(database, User, Role, UserRoles)
security = Security(app, user_datastore)
@user_registered.connect_via(app)
def user_registered_sighandler(sender,**extra):
print("print-user_registered_sighandler")
@user_logged_out.connect_via(app)
def on_user_logged_out(sender, user):
print('USER LOG OUT: made it in',user)
@app.route('/')
def index():
print(user_registered.receivers)
return render_template('base.html')
database.create_tables([User,Role,UserRoles], safe=True)
app.run(debug=True)
基本.html模板:
<!doctype html>
<html>
<head>
<title>Blog</title>
</head>
<body>
<ul>
{% if current_user.is_authenticated() %}
<li><a href="{{ url_for('security.logout',next='/') }}">Log out</a></li>
<li><a href="{{ url_for('security.register') }}">Register</a></li>
{% else %}
<li><a href="{{ url_for('security.login',next='/') }}">Login</a></li>
<li><a href="{{ url_for('security.register') }}">Register</a></li>
{% endif %}
{% block extra_header %}{% endblock %}
</ul>
</body>
</html>
我能够通过以下方式做到这一点:
security = Security(app, user_datastore,
register_form=ExtendedRegisterForm)
@user_registered.connect_via(app)
def user_registered_sighandler(app, user, confirm_token):
default_role = user_datastore.find_role("Pending")
user_datastore.add_role_to_user(user, default_role)
db.session.commit()
user_registered
的导入更改为以下内容:
from flask.ext.security import user_registered
然后信号将在 Python 3.3 中按预期工作,并在用户注册时调用 user_registered_sighandler
函数。
user_registered
信号导入到__init__.py
文件中以确保烧瓶安全,因此它也可用于包的顶层。