【问题标题】:How to show flask foreign key field in modelform with readable display dropdown?如何在具有可读显示下拉列表的模型中显示烧瓶外键字段?
【发布时间】:2020-05-14 23:04:45
【问题描述】:

我的模型中有一对多和多对多的关系。我正在使用wtforms_alchemy ModelForm 创建表单,但ForeignKey 字段没有显示为下拉字段,它也将整数显示为其中的值。我尝试引用类似的问题并尝试了答案,例如,我将__str__() 和__repr__() 函数放入其中,以便它们在下拉列表中返回一些可读且有意义的字符串,但这并没有发生。有谁知道我还能怎么做?

Models.py-


class Product(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), nullable=False)
    location_id = db.Column(db.Integer, db.ForeignKey('location.id'))

    def __init__(self, name, location=None):
        self.name = name
        if location:
            self.location_id = location.id

    def __repr__(self):
        warehouse = Location.query.filter_by(id = self.location_id).first()
        qty = warehouse.get_product_quantity(self.name)
        return '{0}-{1}-{2}'.format(self.name, warehouse.name, qty)

class Location(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), unique=True, nullable=False)
    products = db.relationship('Product', backref='warehouse')

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return 'Location-{0}'.format(self.name)

class Movement(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    from_location_id = db.Column(db.Integer, db.ForeignKey("location.id"))
    to_location_id = db.Column(db.Integer, db.ForeignKey("location.id"))
    from_location = db.relationship(Location, lazy='joined', foreign_keys=[from_location_id], backref='from_location')
    to_location = db.relationship(Location, lazy='joined', foreign_keys=[to_location_id], backref='to_location')
    product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
    product = db.relationship(Product, backref='movements')
    qty = db.Column(db.Integer)

forms.py -

class ProductForm(ModelForm, Form):
    class Meta:
        model = Product
        include = ['name']

class LocationForm(ModelForm, Form):
    class Meta:
        model = Location
        include = ['name']

class MovementForm(ModelForm, Form):
    class Meta:
        model = Movement
        include = ['from_location_id', 'to_location_id', 'product_id', 'qty']

【问题讨论】:

    标签: foreign-keys flask-sqlalchemy dropdown flask-wtforms modelform


    【解决方案1】:

    你需要从你的路由函数中传递选择选项

    使用模型和表单的示例:

    @app.route('/movement/<movement_id>')
    def edit_movement(movement_id):
        products = db.engine.execute("select id, product_name from products")
        form.product.choices = [(p.id, p.product_name) for p in products]
        return render_template('movement.html', movement_id=movement_id, form=form)
    

    【讨论】:

      【解决方案2】:

      由于 ID 是整数,WTForm-ALchemy 会将表单字段转换为整数字段,您可以看到 here

      因此,您可以按照here 的说明强制使用选择字段

      如果您想要更多可读性,可以使用QuerySelectField。

      class MovementForm(ModelForm, Form):
          class Meta:
              model = Movement
      
          product = QuerySelectField(
              query_factory=lambda: Product.query.all(),
              get_pk=lambda a: a.id,
              get_label=lambda a: a.name,
              allow_blank=False,
          )
      

      如果您愿意,可以使用视图/路由来查询并将选项传递给表单。

      def movement_new():
          movement = Movement()
          form = MovementForm(obj=movement)
      
          products = [(c.id, c.name) for c in Product.query.all()]
          form.product_id.choices = products
          ...
      

      然后在 MovementForm 上

      class MovementForm(ModelForm, Form):
          class Meta:
              model = Movement    ---> note tha the include was removed
      
          product_id = SelectField('Product', coerce=int)
        ...
      

      【讨论】:

        猜你喜欢
        • 2012-06-25
        • 2020-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-05
        • 1970-01-01
        • 2017-02-17
        相关资源
        最近更新 更多