gpt4 book ai didi

python - WTForms:从具有关系的 SQLAlchemy 字段设置默认值

转载 作者:太空宇宙 更新时间:2023-11-03 18:26:43 26 4
gpt4 key购买 nike

这里有很多关于 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com