我在烧瓶框架中使用wtforms。当我使用DateTimeField时,我添加了格式参数。
但是datetime格式来自登录的用户
表格
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。
解决此问题的正确方法是什么?
最佳答案
哦,我看到了您的问题,您想要的日期格式正在根据每个请求进行更改。 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
,因为无论如何该字段对象仅用于此请求。更新2:
我编辑了对子类Form而不是BaseForm的答案。 BaseForm是WTForms的低级API的一部分;他们说不要使用它,除非您确定需要。我还将国际化逻辑放在构造函数中,而不是在
process_formdata
中(感谢#pocoo的mattupstate提出这个想法)。我认为这样更清晰一些,在调试器中检查字段将更有意义。现在,以编写代码的方式,您希望在定义表单时将该字段实例化为类属性,这意味着它将不起作用,并且此代码也不是线程安全的。但是由于一些元类的欺骗,实例化表单时,该字段实际上被实例化为实例属性。请注意,如果您使用BaseForm,则该元类的欺骗方法无法正常工作,这是避免使用BaseForm的另一个原因。
更新3:
抱歉,刚刚在IRC上与您交谈,发现您编写了自己的BaseForm,该BaseForm继承了Form。很好:)