- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这里有很多关于 SO 的问题,其标题听起来与我将要描述的内容相似,但据我从几个小时的研究中可以看出,这个问题是独一无二的。所以就这样吧!
我正在编写我的第一个 Flask 应用程序。我使用 SQLAlchemy 作为模型层,使用 WTForms 来处理表单。该应用程序将是一个轻量级的个人财务管理器,我可能实际上不会将其用于严肃的业务。我有一张表列出所有交易,另一张表列出所有费用类别(杂货、服装等)。事务表有一个引用类别表的列(“类别”)。在 View 中,我用一个元素表示类别列表。
我的问题是,在编辑事务时,我无法弄清楚如何告诉 WTForms 将元素设置为特定的预定义值。 (是的,我知道您可以在定义表单时设置默认值,这不是我要问的。)
模型如下所示(删除了不相关的字段):
class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False, unique=True)
# ...
class Trans(db.Model):
# ...
category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
category = db.relationship('Category',
backref=db.backref('trans', lazy='dynamic'))
# ...
表单.py:
def category_choices():
return [('0', '')] + [(c.id, c.name) for c in Category.query.all()]
class TransactionForm(Form):
# ...
category = SelectField('Category', coerce=int, validators=[InputRequired()])
# ...
路线(POST尚未实现):
@app.route('/transactions/edit/<trans_id>', methods=['GET', 'POST'])
def trans_edit(trans_id):
transaction = Trans.query.get(trans_id)
form = forms.TransactionForm(obj=transaction)
form.category.choices = forms.category_choices()
form.category.default = str(transaction.category.id)
#raise Exception # for debugging
return render_template('trans.html',
title='Edit Transaction',
form=form)
最后是模板(Jinja2):
{{ form.category(class='trans-category input-medium') }}
正如您在 route 看到的,我从 transaction.category.id 设置了 form.category.default,但这不起作用。我认为我的问题是我在创建表单后设置“默认”。我不得不这样做,因为模型来自通过 SQLAlchemy 的数据库。根本原因似乎是 form.category 是一个对象(由于关系),WTForms 似乎无法轻松处理。我不可能是第一个遇到这种情况的人...我是否需要重新设计模型以使其与 WTForms 更加兼容?我有什么选择?
谢谢!
最佳答案
我在评论中提到了这一点。听起来您可能会从使用 WTForm 的 SQLAlchemy 扩展中受益。这将为您的转换表单中的类别创建一个下拉列表。
我的示例的用例略有不同。我正在将博客文章与主题相关联。也就是说,许多帖子共享一个主题。我想象在你的例子中,许多交易共享一个类别。
表单
from wtforms.ext.sqlalchemy.fields import QuerySelectField #import the ext.
def enabled_topics(): # query the topics (a.k.a categories)
return Topic.query.all()
class PostForm(Form): # create your form
title = StringField(u'title', validators=[DataRequired()])
body = StringField(u'Text', widget=TextArea())
topic = QuerySelectField(query_factory=enabled_topics, allow_blank=True)
模型这里重要的部分是 a) 确保您正确定义了关系,以及 b.) 将主题添加到您的 init 中,因为您使用它来创建新条目。
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
body = db.Column(db.Text)
# one-to-many with Topic
topic = db.relationship('Topic', backref=db.backref('post', lazy='dynamic'))
def __init__(self, title, body, topic):
self.title = title
self.body = body
self.topic = topic
class Topic(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
def __init__(self, name):
self.name = name
查看这里没什么特别的。只是一个生成表单并处理提交结果的常规 View 。
@app.route('/create', methods=['GET', 'POST'])
@login_required
def create_post():
form = PostForm()
if form.validate_on_submit():
post = Post(title=form.title.data, body=form.body.data,
topic=form.topic.data)
db.session.add(post)
db.session.commit()
Topic.update_counts()
flash('Your post has been published.')
return redirect(url_for('display_post', url=url))
posts = Post.query.all()
return render_template('create_post.html', form=form, posts=posts)
模板这里也没什么特别的。只需确保像基本字段一样呈现模板中的字段即可。不需要花哨的循环,因为 WTForms Sqlalchemy 扩展可以为您完成所有这些工作。
{% extends "base.html" %}
{% block title %}Create/Edit New Post{% endblock %}
{% block content %}
<H3>Create/Edit Post</H3>
<form action="" method=post>
{{form.hidden_tag()}}
<dl>
<dt>Title:
<dd>{{ form.title }}
<dt>Post:
<dd>{{ form.body(cols="35", rows="20") }}
<dt>Topic:
<dd>{{ form.topic }}
</dl>
<p>
<input type=submit value="Publish">
</form>
{% endblock %}
就是这样!现在我的帖子表单有一个主题下拉列表。用您的术语来说,当您加载交易时,该交易的默认类别将在下拉列表中突出显示。正确的说法是,与交易关联的类别是通过 trans 模型中定义的关系加载的。
另请注意,还有一个多选 SQLAlchemy 扩展,以防一个事务具有多个“默认”类别。
现在,我的问题是如何处理多对多关系......我试图将存储在多对多表中的一串标签传递到 TextArea 字段。没有 SQLAlchemy 扩展!
我发布了这个问题here
关于python - WTForms:从具有关系的 SQLAlchemy 字段设置默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23051179/
我正在阅读 http://pythonhosted.org/WTForms/但它没有在任何地方定义过滤器函数的接口(interface),就像在 Field() 构造函数的 filters= 关键字参
在我的表单中,我尝试创建一个带有选择的自定义数组字段。 自定义表单字段: class CustomField(Field): widget = TextInput() def _val
我希望使用 Flask-WTForms 制作一个输入表单,其字段根据其他字段中的内容而变化。 例如,假设有一个“输入联系人”复选框。单击该按钮后,将出现(或激活)新字段,用于输入联系人的姓名和电话号码
这是我在 StackOverflow 上的第一篇文章,大家好。 我正在开发博客应用程序来学习 Python 和 Flask,我想在 Google App Engine 上启动它。不幸的是,我在将 WT
我正在尝试将数据从我的FlaskSQLAlChemy数据库自动填充到FlaskForm。以下是我的代码片段:。我想把这种型号的产品自动填充到一种可以接受购买的形式。以下是我的表格:。这是我的路线:。最
我使用的是最新版本的 flask、wtforms 和 Flask-WTForms。 我有一个显示表单的页面,其中一个是带有选项“A”的选择框。 应用程序启动时一切正常。在另一种形式中,我添加了一条名为
我有一个非常基本的 Flask 应用程序: from flask import Flask, render_template from flask_wtf import FlaskForm from
WTForms已更新为 2.3.0有了突破性的变化。我尝试调整其他要求,例如 werkzeug.1.0.0但还没有运气。有没有人找到解决办法? 这是堆栈跟踪: Traceback (most rece
在 WTForms 中,我可以根据数据库中的数据创建自定义验证器吗? 例如,我想显示一个多选字段,用户只能根据他们的帐户类型(存储在数据库中)选择一定数量的值。 预期的行为是这样的: 如果提交了表单,
我目前正在尝试使用 Flask 构建一个简单的 Web 应用程序。有了这个,我也在使用 WTForms,但是我在从表单中获取日期信息并对其进行验证时遇到了问题。 这是表格: from flask_wt
我有一个带有用户登录系统的 flask 应用程序。我现在注意到一些与用于注册和登录网站的电子邮件地址区分大小写相关的问题。 TL;DR 问题:我如何使用 Flask 表单的小写字母并使用它来评估用户是
我要求的其实很简单。我想创建一个包含一些字段和一个提交和一个取消按钮的表单。我想使用 Flask-Bootstrap 的 quick_form 模板函数来降低模板中的开销。我的表格是这样的: from
可能有更好的方法来执行此操作,但我正在尝试使用隐藏表单在 Flask 中使用 WTForms 定义按钮。当我尝试设置值时,这些字段似乎生成了两次。一次使用默认值“”,一次使用模板中设置的值。最终,在发
是否可以在离开字段后但在提交之前验证 WTForm 字段? 例如,在输入用户名后,在用户单击提交之前,验证该字段以查看其是否可用并显示复选标记。 最佳答案 当字段更改时,执行检查并更改相邻节点中的文本
我发现 IntegerField 在为空时不验证。要重现,请复制以下 block : from flask import Flask, render_template_string from flas
我需要将一个对象从我的数据库传递到我的表单,我想从中读取默认值。我当前的代码如下所示: 我的初始化: form = EditEventForm(event) 还有我的表单类: class EditEv
我正在使用 Flask 和 Flask-WTF,我需要创建一个包含多个具有相似结构的 block (子表单)的表单(例如具有一个 SelectField 和一个 TextAreaField 的子表单)
我需要将一个对象从我的数据库传递到我的表单,我想从中读取默认值。我当前的代码如下所示: 我的初始化: form = EditEventForm(event) 还有我的表单类: class EditEv
已经看过this答案,我无法让我的自定义 WTForm 验证器接受另一个参数。 我的代码的结构是我有一个 form_create() 方法,通过以下方式调用: form = other_fil
我在 Web 应用程序中使用 Python 3.7.4 以及 Flask 1.1.1 和 WTforms 2.2.1。 我正在尝试创建DateField像这样: user_birth = DateFi
我是一名优秀的程序员,十分优秀!