[英]Flask WTFORMS building a SelectField from a table
I am pulling my hair out with this as I haven't had any issues with flask or WTForms and have built quite a large application so far.我正在为此拉扯头发,因为我对 flask 或 WTForms 没有任何问题,并且到目前为止已经构建了相当大的应用程序。 Here is what I am trying to do.这是我想要做的。
I have 2 data models, Subscription, and Billing interval.我有 2 个数据模型,订阅和计费间隔。 There is a foreign key between the two and everything works well:两者之间有一个外键,一切正常:
class Subscriptions(db.Model):
__tablename__ = 'subscriptions'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(64))
description = db.Column(db.String(255))
lastcrawled = db.Column(db.Date)
lastcheckedby = db.Column(db.Integer)
isActive = db.Column(db.Boolean, default = False)
datecreated = db.Column(db.Date, default = datetime.date.today())
pricing = db.Column(db.Numeric(10, 2), nullable=True)
alias = db.Column(db.String(64))
isQuote = db.Column(db.Boolean, default = True)
billinginterval_id = db.Column(db.Integer, db.ForeignKey('billinginterval.id'))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
class BillingInterval(db.Model):
__tablename__ = 'billinginterval'
id = db.Column(db.Integer, primary_key = True)
interval = db.Column(db.String(64))
subscriptions = db.relationship('Subscriptions', backref='billinginterval')
def __str__(self):
return self.interval
I have a form where a user can add another subscription:我有一个表单,用户可以在其中添加另一个订阅:
class AddSubscription(FlaskForm):
name = StringField("Name", validators=[DataRequired()])
description = TextAreaField('Description')
pricing = IntegerField('Pricing')
billinginterval = SelectField('Billing Interval',choices=BillingInterval.query.all())
submit = SubmitField("Add Subscription")
And finally here is my Template:最后是我的模板:
{% extends "layout.html" %}
{% block content %}
<form method="POST">
{# This hidden_tag is a CSRF security feature. #}
{{ form.hidden_tag() }}
{{ form.name.label }} {{ form.name() }}<br>
{{ form.description.label }} {{ form.description() }}<br>
{{ form.pricing.label }} {{ form.pricing() }}<br>
{{ form.billinginterval.label }} {{ form.billinginterval() }}<br>
{{ form.submit() }}
</form>
{% endblock %}
I need to have a "SelectField" that populates from the "billinginterval" table (displays interval as the choices) and then writes the billinginterval.id field to the subscription model.我需要一个从“billinginterval”表中填充的“SelectField”(显示间隔作为选项),然后将 billinginterval.id 字段写入订阅 model。
Everything works flawlessly until I try adding this billing interval dropdown.在我尝试添加此计费间隔下拉列表之前,一切都完美无缺。 Just can't get it.就是拿不到。
I've tried everything, I cannot get it to work.我已经尝试了一切,我无法让它工作。 Any help would be grateful.任何帮助将不胜感激。 Thanks!谢谢!
Ok.... I figured this out.好的....我想通了。 Not sure it is the best way.不确定这是最好的方法。
In my Forms.py file I modified the select field:在我的 Forms.py 文件中,我修改了 select 字段:
class AddSubscription(FlaskForm):
name = StringField("Name", validators=[DataRequired()])
description = TextAreaField('Description')
pricing = IntegerField('Pricing')
#Right HERE!!!!
billinginterval = SelectField('Billing Interval',choices=[], coerce=int, validate_choice=True)
#billinginterval = SelectField('Billing Interval',choices=[(1,'Monthly'),(2,'Daily')])
#billinginterval = QuerySelectField(query_factory=lambda: BillingInterval.query.all())
#billinginterval = QuerySelectField(query_factory=billinginterval_query, allow_blank=True)
submit = SubmitField("Add Subscription")
I added ",choices=[], coerce=int, validate_choice=True)" to the billinginterval form field.我在 billinginterval 表单字段中添加了“,choices=[], coerce=int, validate_choice=True)”。
Then in my views.py (routing file) I set the choices variable:然后在我的views.py(路由文件)中设置选择变量:
def addsubscription(userid):
form = AddSubscription()
form.billinginterval.choices = [(interval.id, interval.interval) for interval in BillingInterval.query.all()]
#print(form.billinginterval.data)
if form.validate_on_submit():
subscription = Subscriptions(name=form.name.data,
description=form.description.data,
lastcheckedby=current_user.id,
isActive=True,
user_id=userid,
billinginterval_id=form.billinginterval.data,
alias = random.getrandbits(32))
db.session.add(subscription)
db.session.commit()
subscriptions = Subscriptions.query.all()
#flash('Thanks for registering! Now you can login!')
return redirect(url_for('admin.managesubscriptions', userid=userid))
return render_template('addsubscription.html', form=form)
```
And loaded it manually from my data model.
All works now. Hope this solution helps someone!
The best practice is to load the choices
in the __init__
method of your AddSubscription
class:最佳做法是在AddSubscription
class 的__init__
方法中加载choices
:
class AddSubscription(FlaskForm):
name = StringField("Name", validators=[DataRequired()])
description = TextAreaField('Description')
pricing = IntegerField('Pricing')
billinginterval = SelectField('Billing Interval', coerce=int)
submit = SubmitField("Add Subscription")
def __init__(self, *args, **kwargs):
super(AddSubscription, self).__init__(*args, **kwargs)
self.billinginterval.choices = [(interval.id, interval.interval)
for interval in BillingInterval.query.all()]
Then you will not load the choices
in every view functions where you will use AddSubscription
form.然后,您将不会在将使用AddSubscription
表单的每个视图函数中加载choices
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.