小编Dav*_*ite的帖子

如何使用Flask和Flask-login传递"下一个"URL?

Flask-login的文档讨论了处理"下一个"URL的问题.这个想法似乎是:

  1. 用户去了 /secret
  2. 用户重定向到登录页面(例如/login)
  3. 成功登录后,用户将被重定向回 /secret

我发现使用Flask-login的唯一半完整示例是https://gist.github.com/bkdinoop/6698956.它很有用,但由于它不包含HTML模板文件,我看到我是否可以将它们重新创建为自我训练练习.

这是/secret/login部分的简化版本:

@app.route("/secret")
@fresh_login_required
def secret():
    return render_template("secret.html")

@app.route("/login", methods=["GET", "POST"])
def login():
    <...login-checking code omitted...>
    if user_is_logged_in:
        flash("Logged in!")
        return redirect(request.args.get("next") or url_for("index"))
    else:
        flash("Sorry, but you could not log in.")
        return render_template("login.html")
Run Code Online (Sandbox Code Playgroud)

这是login.html:

<form name="loginform" action="{{ url_for('login') }}" method="POST">
Username: <input type="text" name="username" size="30" /><br />
Password: <input type="password" name="password" size="30" /><br />
<input type="submit" value="Login" /><br />
Run Code Online (Sandbox Code Playgroud)

现在,当用户访问时/secret,他被重定向到 …

python forms flask flask-login

15
推荐指数
1
解决办法
1万
查看次数

我可以“触摸”SQLAlchemy 记录以触发“onupdate”吗?

这是一个 SQLAlchemy 类:

class MyGroup(Base):
    __tablename__ = 'my_group'
    group_id = Column(Integer, Sequence('my_seq'), primary_key=True)
    group_name = Column(String(200), nullable=False, index=True)
    date_created = Column(DateTime, default=func.now())
    date_updated = Column(DateTime, default=func.now(), onupdate=func.now())
Run Code Online (Sandbox Code Playgroud)

每当我添加 group_name 或(例如)更新 group_name 时,该date_updated字段都会更新。那太棒了。

但有时在某些情况下,即使组记录本身没有更改(例如,如果更新了不同但相关表中的数据),我也想将组标记为“已更新”。

我可以手动完成:

group = session.query(MyGroup).filter(MyGroup.group_name=='Some Group').one()
group.date_updated = datetime.datetime.utcnow()
session.commit()
Run Code Online (Sandbox Code Playgroud)

但我真的宁愿让模型以自己的方式来做,而不是重新创建一个 Python 进程来手动更新日期。(例如,为了避免模型可能使用now()而手动功能错误使用的错误utcnow()

SQLAlchemy 有没有办法“触摸”一个记录(有点像 UNIX touch),它不会改变记录的任何其他值但会触发该onupdate=函数?

python sqlalchemy sql-update

7
推荐指数
1
解决办法
4014
查看次数

Flask-WTF:缺少 CSRF 令牌

一个看似简单的错误——由于“CSRF 令牌丢失”错误而无法通过的表单提交——已经变成了令人费解的一天。我已经阅读了所有与 Flask 或 Flask-WTF 相关的 SO 文章,并且缺少 CSRF 令牌,但似乎没有任何帮助。

以下是详细信息:

遵循Martijin对先前问题的指导方针

如果出现以下情况,Flask-WTF CSRF 基础设施将拒绝令牌:

1)令牌丢失。不是这里的情况,您可以在表单中看到令牌。

令牌肯定存在于我的表单中,并且已成功发布

2)它太旧了(默认过期时间设置为 3600 秒,或一个小时)。在表单上设置 TIME_LIMIT 属性以覆盖它。可能不是这里的情况。

对我来说也可以 - 令牌完全在默认到期时间内

3) 如果在当前会话中没有找到 'csrf_token' 密钥。您显然可以看到会话令牌,所以这也是。

就我而言, session['csrf_token'] 已正确设置并被 Flask 看到

4)如果HMAC签名不匹配;签名基于会话中在“csrf_token”密钥下设置的随机值、服务器端机密和令牌中的到期时间戳。

这是我的问题。提交表单的 CSRF 和会话 CSRF 之间的 HMAC 比较失败。然而我不知道如何解决它。我已经非常绝望(就像其他提问者一样)深入研究 Flask-WTF 代码并设置调试消息以找出发生了什么。据我所知,它是这样工作的:

1)generate_csrf_token()在“form.py”(Flask-WTF)中想要生成一个CSRF令牌。所以它调用:

2)generate_csrf()在“csrf.py”中。如果不存在,该函数会生成一个新的 session['csrf_token']。 在我的情况下,这总是发生- 尽管其他会话变量似乎在请求之间持续存在,但我的调试显示在请求开始时我的会话中从未有“csrf_token”。这是正常的吗?

3)当我在模板上呈现隐藏字段时,生成的令牌被返回并可能合并到表单变量中。(再次,调试显示此令牌存在于表单中并正确提交和接收)

4) 接下来,提交表单。

5) 现在,validate_csrf在 csrf.py 中被调用。但是由于发生了另一个请求,并且 generate_csrf() 生成了一个新的会话 CSRF 令牌,这两个令牌(在会话中和来自表单中)的两个时间戳将不匹配。由于 CSRF 部分由到期日期组成,因此验证失败。

我怀疑问题出在步骤 #2 中,其中为每个请求生成一个新令牌。但是我不知道为什么我的会话中的其他 …

python session flask wtforms flask-wtforms

7
推荐指数
2
解决办法
1万
查看次数

Python 中的 webargs / Marshmallow 可以修改字段,而不仅仅是验证它吗?

我将 Flask 与 Flask-restful 和webargs(使用Marshmallow作为后端)一起使用。目前我可以通过以下方式提取我想要的字段:

class AddGroup(Resource):
    args = {
        'name': fields.Str(missing=None),
        'phone': fields.Str(missing=None),
    }

    @use_args(args)
    def get(self, args):
        name = args['name'].strip()
        # ... some GET-related code ...

    @use_args(args)
    def post(self, args):
        name = args['name'].strip()
        # ... some POST-related code ...
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好。但我真正想做的是确保args['name']进入各种方法(“post”、“get”等)时已经删除了空格,这样我就不必每次都手动处理每个变量。(剥离空白只是一个例子 - 它可能是其他一些简单或复杂的转换)

有没有一种方法(通过覆盖 String 字段、定义我自己的字段或其他方式)允许args在到达类方法之前对其进行预处理?

python flask flask-restful webargs marshmallow

5
推荐指数
1
解决办法
2112
查看次数

SQLAlchemy 中是否有 LISTAGG WITHIN GROUP 等价物?

这是一个简单的 Oracle 表:

+-----------+---------+
|   food    | person  |
+-----------+---------+
| pizza     | Adam    |
| pizza     | Bob     |
| pizza     | Charles |
| ice cream | Donald  |
| hamburger | Emma    |
| hamburger | Frank   |
+-----------+---------+
Run Code Online (Sandbox Code Playgroud)

这是我想做的聚合 SELECT 的结果:

+-----------+------------------+
|   food    |      people      |
+-----------+------------------+
| hamburger | Emma,Frank       |
| ice cream | Donald           |
| pizza     | Adam,Bob,Charles |
+-----------+------------------+
Run Code Online (Sandbox Code Playgroud)

在 Oracle 11g+ 中,使用 LISTAGG 就很容易了:

SELECT food, LISTAGG (person, ',') …
Run Code Online (Sandbox Code Playgroud)

python oracle sqlalchemy oracle12c listagg

5
推荐指数
1
解决办法
2067
查看次数

Flask为什么不给我提供交互式调试器?

这是一个简单的Flask应用,出现语法错误(应该是sys.version,而不是sys.version()

from flask import Flask, url_for, request, render_template
import sys

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

@app.route('/')
def index():
    version = sys.version()
    return "This is the index page.  Python version info: {}".format(version)

if __name__ == '__main__':
    app.run(debug=True)
Run Code Online (Sandbox Code Playgroud)

当我在本地运行它并尝试访问http:// localhost:5000时,我得到了不错的Werkzeug调试器:

在此处输入图片说明

但是当我在远程服务器(Apache 2.4.17,mod_wsgi 4.4.21)上运行它时,我只得到一个通用的500错误页面:

在此处输入图片说明

我已经尝试了各种方法来使这项工作:

  • app.debug = True之后app = Flask(__name__)
  • 基于此链接,我也尝试添加以下代码:

from werkzeug.debug import DebuggedApplication application = DebuggedApplication(app, True)

但似乎无济于事。

我知道调试器无法在派生环境中工作,但是根据此链接,mod_wsgi的默认模式是派生。我的Apache配置为:

WSGIDaemonProcess flasktest user=david group=devgrp threads=1 python-path=/apps/www/80/wsgi-scripts/FlaskTest:/apps/.virtualenvs/flasktest/lib/python3.4/site-packages
Run Code Online (Sandbox Code Playgroud)

那为什么不能得到漂亮的调试器呢?

编辑:这是我添加的修改文件(无效) …

python apache mod-wsgi werkzeug flask

4
推荐指数
1
解决办法
1821
查看次数

如何使用 Flask-Restful 访问具有多个端点的资源?

这是一个简单的 Flask-Restful 资源:

class ListStuff(Resource):
    def get(self):
       stuff = SomeFunctionToFetchStuff()
       if re.match('/api/', request.path):
           return {'stuff': stuff}
       return make_response("{}".format(stuff), 200, {'Content-Type': 'text/html'})

api.add_resource(ListStuff, '/list', '/api/list', endpoint='list')
Run Code Online (Sandbox Code Playgroud)

我的想法是允许用户同时调用/list/api/list。如果他们使用第一个 URL,他们将返回数据的 HTML 表示。如果他们使用第二个 URL,他们将获得 JSON 表示。

我的问题是当我想在程序的其他地方访问这个端点的 URL 时。我不能只使用url_for('list'),因为/list无论用户是否访问http://host.example.com/list或访问,它总会返回http://host.example.com/api/list

那么我该如何构建 URL/api/list呢?

python rest flask flask-restful

3
推荐指数
1
解决办法
3285
查看次数

为什么我的 Flask 错误处理程序没有被调用?

我正在尝试使用“实现 API 异常”页面上的指南在 Flask 1.0.2 和 Flask-RESTful 0.3.7 中创建自定义错误处理程序。(Flask-RESTful 有它自己的创建自定义错误消息的方法,但由于它似乎没有办法在异常发生时接受自定义错误消息,因此我尝试改用 vanilla Flask 方法。)

from flask import Flask, jsonify
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

#########################################

class MyGenericException(Exception):
    status_code = 500
    def __init__(self, message, status_code=None, payload=None):
        Exception.__init__(self)
        self.message = message
        if status_code is not None:
            self.status_code = status_code
        self.payload = payload
    def to_dict(self):
        rv = dict(self.payload or ())
        rv['message'] = self.message
        return rv

@app.errorhandler(MyGenericException)
def handle_generic_error(error):
    response = jsonify(error.to_dict())
    response.status_code = error.status_code …
Run Code Online (Sandbox Code Playgroud)

python error-handling exception flask flask-restful

3
推荐指数
1
解决办法
3400
查看次数