我的模型中具有一对多关系。我正在使用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']
由于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 ...
Then on MovementForm
class MovementForm(ModelForm, Form):
class Meta:
model = Movement ---> note tha the include was removed
product_id = SelectField('Product', coerce=int)
...