WTForms文档非常不合适,它们甚至没有向您显示自定义窗口小部件的一个示例,该窗口小部件不是从另一个窗口小部件派生的.
我想创建一个按钮类型,这不是<input>在HTML中:
submit = InlineButton(name='submit', type='submit', title='Save this page', textWithinSpan='Save')
Run Code Online (Sandbox Code Playgroud)
这就是我正在尝试的:
from flask.ext.wtf import Required, Length, EqualTo, Field, TextInput, html_params
from flask import Markup
class InlineButtonWidget(object):
text = ''
html_params = staticmethod(html_params)
def __init__(self, input_type='submit', **kwargs):
self.input_type = input_type
def __call__(self, field, **kwargs):
kwargs.setdefault('id', field.id)
kwargs.setdefault('type', self.input_type)
if 'value' not in kwargs:
kwargs['value'] = field._value()
return Markup('<button type="submit" %s><span>%s</span></button>' % (self.html_params(name=field.name, **kwargs), kwargs['textWithinSpan']))
class InlineButton(Field):
widget = InlineButtonWidget()
def __init__(self, label='', **kwargs):
self.widget = InlineButtonWidget('submit', label)
def __call__(self, …Run Code Online (Sandbox Code Playgroud) 我正在使用venv,我开发使用eclipse.我想添加一个联系页面.
我做了:
$ . bin/activate
$ pip install flask-wtf
Run Code Online (Sandbox Code Playgroud)
我在forms.py中导入了一些模块:
我用过这个:
from flask.ext.wtf import Form, TextField, TextAreaField, SubmitField
Run Code Online (Sandbox Code Playgroud)
然后这个:
from flask.ext.wtf import Form
from wtforms.fields import TextField, BooleanField
Run Code Online (Sandbox Code Playgroud)
没有人工作,因为我有这个错误:
from flask.ext.wtf import Form
File "/usr/local/lib/python2.7/dist-packages/flask/exthook.py", line 87, in load_module
raise ImportError('No module named %s' % fullname)
ImportError: No module named flask.ext.wtf
Run Code Online (Sandbox Code Playgroud) 这是我的HTML下拉菜单.该值是子表的主键.
<select id="category" name="category">
<option selected value="__None"></option>
<option value="1">Category Number One</option>
<option value="2">Category Number Two</option>
</select>
Run Code Online (Sandbox Code Playgroud)
我需要使用值整数1而不是"类别编号一"更新Post.category_id.这是我的代码.
# create new post
@app.route('/admin/post', methods=['GET', 'POST'])
@login_required # Required for Flask-Security
def create_post():
form = PostForm()
if form.validate_on_submit():
post = Post(title=form.title.data,
body=form.body.data,
pub_date=form.pub_date.data,
cateogry_id=form.category.data)
db.session.add(post)
db.session.commit()
flash('Your post has been published.')
return redirect(url_for('admin'))
posts = Post.query.all()
return render_template('create_post.html', form=form, posts=posts)
Run Code Online (Sandbox Code Playgroud)
我试过制作......
cateogry_id=form.category.data
cateogry_id=form.category.value
Run Code Online (Sandbox Code Playgroud)
现在不是那么好!
我通过Flask-WTF非常简化的wiki阅读,并且无法理解我能用它做什么.我的印象是<form>html 的部分现在只能看起来像
<form method="post">
{{ form.hidden_tag() }}
{{ form.name }}
<input type="submit">
</form>
Run Code Online (Sandbox Code Playgroud)
但我真的想要使用物化的样式,例如:
<div class="row">
<div class="input-field col s6">
<i class="material-icons prefix">account_circle</i>
<input value="FN" id="first_name" type="text" class="validate">
<label class="active" for="first_name">First Name</label>
</div>
<div class="input-field col s6">
<input value="LN" id="last_name" type="text" class="validate">
<label class="active" for="last_name">Last Name</label>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
我在哪里能适应{{ form.first_name }}并{{ form.last_name }}进入?
编辑:让我详细说明我的答案:例如,我想要像Materialized datepicker(一个很好的弹出日历,让用户选择日期),这应该在<input class='datepicker' length="50">,但现在我正在替换整<input>行与{{ form.date }}...我失去了编辑课程的特权,但没有.
我在WTForms表格中有这个字段
name = StringField('Name', validators = [Optional(), Length(max = 100)])
Run Code Online (Sandbox Code Playgroud)
当字段提交为空form.name.data时,将按预期包含空字符串.
有没有办法让它返回None而不是空字符串?这只是因为null在数据库中处理非常方便,如下所示update:
update t
set
name = coalesce(%(name)s, name),
other = coalesce(%(other)s, other)
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,我不需要检查字段是否为空,并在SQL代码中的Python代码中采取相应的操作.在null与coalesce解决了容易.
我正试图在我的一个烧瓶视图中实现Select2字段.基本上我想在烧瓶应用程序视图中使用相同的select2字段(不是烧瓶管理模型视图),就像在Flask-admin模型创建视图中一样.目前我的解决方案QuerySelectField来自于看起来像这样的wtforms
class TestForm(Form):
name= QuerySelectField(query_factory=lambda: models.User.query.all())
Run Code Online (Sandbox Code Playgroud)
这让我加载和选择我需要的所有数据,但它不提供选择2搜索框等.目前,所有我发现是Select2Field和Select2Widget从瓶/管理/表格/域和瓶/管理/表格/部件同样像这篇文章/sf/ask/1725147231/ 以及http://ivaynberg.github.io/select2/上的 select2文档
据我了解这些可以重复使用,这意味着不需要其他自定义小部件,自定义字段.
如果有人可以提供有关在应用程序中的select2字段实现的更多信息(包括视图,模板,表单文件以及如何正确地"连接"必要的js和css文件,以及如何使用数据库模型加载字段,将不胜感激需要).
由于某种原因,我需要在里面声明一个字段,__init__()所以我可以制作任意类型的FormField.
举个例子form.py:
class PurchaseForm(Form):
item_class = ItemForm
transaction_items = FieldList(FormField(item_class),
label='items',
min_entries=1)
def __init__(self, item_class, *args, **kwargs):
super().__init__(*args, **kwargs)
self.item_class = item_class
self.transaction_items = FieldList(FormField(self.item_class),
label='items',
min_entries=1)
Run Code Online (Sandbox Code Playgroud)
如果我这样做,该transaction_items字段不会被替换__init__(),我可以做一些事情来覆盖它吗?或者setattr为这个特定的例子做些什么?
编辑:这是我如何指定构造函数
import form
@app.route('/add/purchase-transaction', methods=['GET', 'POST'])
def add_purchase_transaction():
form = forms.PurchaseForm(form.ItemForm)
if form.validate_on_submit():
# do something
return render_template('add-purchase-transaction.html', form=form)
Run Code Online (Sandbox Code Playgroud)
所以我的目标是做一个PurchaseForm具有FieldList包含ItemForm窗体类,并在将来,我可以换ItemForm到不同的类,例如PurchaseItemForm
一个看似简单的错误——由于“CSRF 令牌丢失”错误而无法通过的表单提交——已经变成了令人费解的一天。我已经阅读了所有与 Flask 或 Flask-WTF 相关的 SO 文章,并且缺少 CSRF 令牌,但似乎没有任何帮助。
以下是详细信息:
如果出现以下情况,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 中,其中为每个请求生成一个新令牌。但是我不知道为什么我的会话中的其他 …
这是 wtform 的提交按钮代码:
{{ form.submit(class="w-50 btn btn-primary btn-sm submit-btn") }}
Run Code Online (Sandbox Code Playgroud)
我正在考虑在单击时向其添加一个类?我知道通过添加这样的类来显示 wtform+jinja2 中的错误的方法:
{% if reg_form.confirm_password.errors %}
{{ reg_form.confirm_password(class="form-control form-control-sm is-invalid") }}
<div class="invalid-feedback">
{% for error in reg_form.confirm_password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ reg_form.confirm_password(class="form-control form-control-sm")}}
{% endif %}
Run Code Online (Sandbox Code Playgroud)
我查看了 SubmitField 的文档,但我看不到禁用它的方法。https://wtforms.readthedocs.io/en/stable/fields.html
我在使用flask-wtf 为restapi 禁用csrf 时遇到问题。问题与此处类似:由于 Flask-WTF 的 CSRF 保护,Flask-Restful POST 失败,但我使用 flask original 而不是 flask-restful。
我使用了@csrf.exempt装饰器,而且我确实像文档一样,但仍然无法禁用 csrf。这是我的代码,你知道是什么问题吗?
我的应用程序
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField
from flask_wtf.csrf import CSRFProtect
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
app.config['SECRET_KEY'] = "secret"
db = SQLAlchemy(app)
csrf = CSRFProtect(app) # initialize the csrf protect
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String())
class myForm(FlaskForm):
username = StringField("user name")
@app.route("/check", …Run Code Online (Sandbox Code Playgroud) flask-wtforms ×10
python ×9
flask ×8
wtforms ×7
flask-admin ×1
jinja2 ×1
packages ×1
python-venv ×1
session ×1