Flask 将表单中的选择翻译成指向另一个的外键 Table

Flask Translate Choice in Form To ForeignKey Pointing to Another Table

应用程序的这一部分有效,但它很丑陋且不可持续。需要更先进的解决方案。

我正在尝试解决的问题:

应用程序的这一部分使用户能够访问表单以输入他们购买的商品并将其存储在 Postgres 数据库中。我正在使用 Flask SQLAlchemy ORM。 在我的 purchase table 中存在一个字段 store_id,它与我的 store table 有外键关系。我不希望我的用户在表单中 select 商店 ID #,因此我使用 SelectField 来让他们选择商店名称。但是,我似乎无法找到一种可持续的方式将商店名称翻译回其关联的 ID。现在我正在使用下面看到的丑陋的 IF 语句。

有什么更好的方法可以map/translate 将名称存储到我的数据库中 "store" table 中的 ID?

我的模特:

class Purchase(db.Model):
id = db.Column(db.Integer, primary_key=True)
item = db.Column(db.String(80))
quantity = db.Column(db.Integer)
unit_cost = db.Column(db.Integer)
total_cost= db.Column(db.Integer)
date = db.Column(db.DateTime)
store_id = db.Column(db.Integer, db.ForeignKey('store.id'))

我的表格:

class CreatePurchase(FlaskForm):

item = StringField('Item', validators=[DataRequired()])
quantity = IntegerField('Quantity', validators=[DataRequired()])
unit_cost = IntegerField('Unit Cost', validators=[DataRequired()])
total_cost = IntegerField('Total Cost', validators=[DataRequired()])
store_id = SelectField("Store Selector", choices=[('0','Select Store'),('1','Furgesons'), ('2','Ocean State'), ('3','Chewy'), ('4','Amazon'),  ('5', 'Rumford')])
date = DateField('Purchase Date', validators=[DataRequired()])
submit = SubmitField('Enter')

我的路线:

@main.route('/enter_purchases', methods=['GET', 'POST'])
def enter_purchase():

form = CreatePurchase()

x = str(form.store_id) # this is a store name from our form
p = 0
if "Ocean State" in x:
    p = 2
elif "Amazon" in x:
    p = 4
elif "Furgesons" in x:
    p = 1
elif "Chewy" in x:
    p = 3
elif "Rumford" in x:
    p = 5


if form.validate_on_submit():
    purchase = Purchase(item=form.item.data, quantity=form.quantity.data, unit_cost=form.unit_cost.data,
                total_cost=form.total_cost.data, date=form.date.data,store_id=p)

    db.session.add(purchase)
    db.session.commit()
    flash('New purchase added successfully')
    return redirect(url_for('main.success'))
return render_template('enter_purchases.html', form=form)

您有一个 store table,带有数字 ID(作为 PK)和名称属性:

class Store(db.Model):
     store_id = ..
     store_name = ..

您使用 store_name 中的所有 唯一 值填充表单。这需要是动态生成的表单,因此不要使用静态创建的表单,而是执行以下操作:

def CreatePurchase()
    class TempForm(FlaskForm):
        item = StringField('Item', validators=[DataRequired()])
        quantity = IntegerField('Quantity', validators=[DataRequired()])
        unit_cost = IntegerField('Unit Cost', validators=[DataRequired()])
        total_cost = IntegerField('Total Cost', validators=[DataRequired()])
        date = DateField('Purchase Date', validators=[DataRequired()])
        submit = SubmitField('Enter')
    choices = ## some SQLalchemy code to get all unique store_names from the table
    TempForm.store_id = SelectField("Store Selector", choices=choices)
    return TempForm()

然后form.store_id会提供正确的id,但是会在表单中显示店铺的字符串名称。

此设置的关键是确保您使用正确的 SQLalchemy 代码动态填充 SelectField。基本上,对于 table 中的每个商店,您都可以像这样迭代:

choices = list()
for store in Store.query.all():  # <- assumes store_id and store_names are unique
    choices.append((store.store_id, store.store_name))