I have three tables: components, attributes and attribute_values. Each component can have many attribute_values. Each attribute_value belongs to one attribute. Yeah, it's the dreaded EAV pattern...
I have created these two forms:
class AttributeValueForm(Form):
attribute = HiddenField()
value = StringField('Value')
class ComponentForm(Form):
... non-related fields left out ...
attribute_values = FieldList(FormField(AttributeValueForm))
These are the SQLAlchemy models:
class Component(db.Model):
__tablename__ = 'components'
id = db.Column(db.Integer, primary_key=True)
... non-related columns left out ...
class AttributeValue(db.Model):
__tablename__ = 'attribute_values'
id = db.Column(db.Integer, primary_key=True)
value = db.Column(db.String)
attribute_id = db.Column(db.Integer, db.ForeignKey('attributes.id'))
attribute = db.relationship('Attribute', backref='attribute_values'))
component_id = db.Column(db.Integer, db.ForeignKey('components.id'))
component = db.relationship('Component', backref='attribute_values'))
def Attribute(db.Model):
__tablename__ = 'attributes'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(60))
My problem is that I would like to see the name of the attribute as the label of the value field (replacing 'Value'). I've been trying to wrap my head around how WTForms work internally, but I can't see any obvious way to do this.
Any hints appreciated. I could even do with a hack that just renders a custom label, if I could only get hold of the AttributeValue object while rendering the value field.
Ok, so I came up with a solution, which is a bit similar to adarsh's second comment to his answer, but overriding init of the Form used by the FormField:
class AttributeValueForm(Form):
value = StringField('Unnamed attribute')
def __init__(self, *args, **kwargs):
super(AttributeValueForm, self).__init__(*args, **kwargs)
if 'obj' in kwargs and kwargs['obj'] is not None:
self.value.label.text = kwargs['obj'].attribute.name
You could consider using ModelForm
from wtforms-alchemy
You could the define the form with the model quite easily.
Something like:
class AttributeValueForm(ModelForm):
class Meta:
model = Attribute
only = (... columns that you want to include ...)
来源:https://stackoverflow.com/questions/29378241/make-wtforms-set-field-label-from-database-model