我正在使用带有烧瓶框架的wtforms。当我使用DateTimeField时我添加格式参数。 但是日期时间格式来自用户登录
forms.py
from flask import g
from wtforms import *
import wtforms.validators as v
from flask.ext.babel import lazy_gettext as _
from flask.ext.babel import npgettext as _n
from app.app import app
from app.base_forms import *
from app.modules.post.models import *
class PostForm(BaseForm):
post_date = DateTimeField("Post Date", format = app.config.get("DATETIME_FORMAT"), validators =[v.Required(message=_("Post date is required"))] )
我在请求之前设置了app.config.get(“DATETIME_FORMAT”)的值
@app.before_request
def before_request():
if g.user.language == "tr"
app.config["DATETIME_FORMAT"] = "%d.%m.%Y %H:%M"
else:
app.config["DATETIME_FORMAT"] = "%m-%d-%Y %H:%M"
我的申请结构
/app
/modules
/post
/controllers.py
/forms.py
/models.py
/app.py
/run.py
/app/app.py
的内容from flask import Flask, url_for, g, request, redirect, render_template
app = Flask(__name__)
app.config.from_object('app.config.config.ConfigDevelopment')
# Import Modules
from modules.post.controllers.admin import module as modulePostAdmin
app.register_blueprint(modulePostAdmin)
# other codes here
@app.before_request
def before_request():
if g.user.language == "tr"
app.config["DATETIME_FORMAT"] = "%d.%m.%Y %H:%M"
else:
app.config["DATETIME_FORMAT"] = "%m-%d-%Y %H:%M"
/run.py的内容
from app.app import app
app.run(host='localhost', port=8080, debug=True)
当我启动应用程序时,它会抛出错误“KeyError:'DATETIME_FORMAT'”。我认为forms.py在请求之前加载,因此它会抛出keyError。 解决这个问题的正确方法是什么?
答案 0 :(得分:2)
哦,我看到了您的问题,您想要的日期格式会根据请求进行更改。 app.config
无法帮助您解决此问题。
这就是我要做的事情:
from flask import g
from wtforms import DateTimeField
class I18NDateTimeField(DateTimeField):
def __init__(self, label=None, validators=None, format=None, **kwargs):
if g.user.language == "tr"
format = "%d.%m.%Y %H:%M"
else:
format = "%m-%d-%Y %H:%M"
super(I18NDateTimeField, self).__init__(label=label, validators=validators, format=format, **kwargs)
class PostForm(Form):
post_date = I18NDateTimeField("Post Date", validators =[v.Required(message=_("Post date is required"))] )
你(大部分)对,before_request
尚未被召唤。也就是说,表单定义根本不会发生在请求上下文中,它会在导入应用程序时发生,早在任何请求到达之前,它就不会发生多次。
但是,对于每个请求,表单及其字段将再次实例化,这就是为什么这样做的原因。可以在此处修改self.format
,因为此字段对象仅用于此请求。
我编辑了我的子类Form而不是BaseForm的答案。 BaseForm是WTForms的低级API的一部分;他们说不要使用它,除非你确定你需要。我还将这种国际化逻辑放在构造函数而不是process_formdata
中(感谢来自#pocoo的mattupstate的想法)。
我认为这样更清晰,在调试器中检查字段会更有意义。现在,编写代码的方式,您希望在定义表单时将字段实例化为类属性,这意味着无法工作,并且此代码不会是线程 - 安全。但是由于某些元类欺骗,当实例化表单时,该字段实际实例化为实例属性。请注意,如果使用BaseForm,那么元类欺骗无法正常工作,这是避免BaseForm的另一个原因。
抱歉,刚刚在IRC上与您交谈,发现您编写了自己的BaseForm子类Form。这完全没问题。)
答案 1 :(得分:0)
我不确定当你这样做时是否会正确配置。您的app.config
可能不在应用中,因为您制作它的结构。你是否像app = Flask(__name__)
那样进行了导入?
您可以使用应用工厂模式解决此问题
# app/__init__.py
def create_app():
app = Flask(__name__)
app.config.from_object('app.settings.default')
from app.yourforms import bp
app.register_blueprint(bp)
return app
您可以在单独的文件中制作蓝图,如下所示:
# yourforms/__init__.py
from flask import Blueprint
bp = Blueprint('forms', __name__)
from . import views
然后在同一目录的views.py
文件中,使用蓝图
from flask import current_app
from . import bp
from .forms import PostForm
@bp.before_app_request
def set_datetime_format():
# your code
# access app's config with current_app.config.get('YOURKEY')
那么你只需稍微调整一下你的runfile就可以了:
if __name__ == '__main__':
app = create_app()
app.run()