Reputation: 4374
I have a Flask-SQLAlchemy site which uses the SQLAlchemy enum type for certain columns, to restrict possible input values.
For example, I have a "payment type" enum that has a few payment type options, like so:
class PaymentType(enum.Enum):
fixed = "fixed"
variable = "fixed_delivery"
quantity_discount = "quantity_discount"
When I use this in a dropdown/select I can specify the options like so:
prd_payment_type = SelectField(_('prd_payment_type'), choices=SelectOptions.PaymentTypes.All(0, _('PleaseSelect')))
The All() function I'm calling returns the different enum values as options, and also adds a custom "Please select..." option to the dropdown list. It looks like this:
class PaymentTypes(object):
@staticmethod
def All(blank_value=None, blank_text=None):
ret = [(i.value, _(i.name)) for i in PaymentType]
SelectOption.add_blank_item(ret, blank_value, blank_text)
return ret
So far, so good, I get a nice dropdown, with the correct options. the problem arises when I want to display the form using an already existing SQLAlchemy object from the database.
When I fetch the object from SQLAlchemy, the prd_payment_type property contains the enum PaymentType.quantity_discount
, not just a string value 'quantity_discount':
Because WTForms (presumably) matches the pre-selected option in the dropdown to a string value "quantity_discount", it doesn't match the enum in the SQLAlchemy model and the option is not selected in the dropdown.
The SelectField
of WTForms accepts a list of tuples containing strings as choices. I can't feed it my enum.
On the other hand, the SQLAlchemy model returns an enum type as the property for prd_payment_type. I could maybe override this property or something, but that feels like a lot of work to support SQLAlchemy's enums in WTForms.
Is there a standard solution for working with SQLAlchemy's enums in a WTForms SelectField or should I abandon using enums altogether and just store strings, maybe from a list of constants to keep them in check?
Upvotes: 1
Views: 1119
Reputation: 4374
I have found a solution myself. It seems that when the enum has a
def __str__(self):
return str(self.value)
That's enough for WTForms to match the database value to the SelectField value. I have made a baseclass that derives from enum.Enum and added the code above to return the enum value as a string representation.
This solution was based on these similar problems I found later on:
https://github.com/flask-admin/flask-admin/issues/1315
Python Flask WTForm SelectField with Enum values 'Not a valid choice' upon validation
Upvotes: 1