0

I have a set of SelectField with Flask-WTF and I convert the default language with Flask-Babel.

Here is the snippet of my code:

from flask_babel import _, lazy_gettext as _l class PaymentStatus(enum.Enum): PENDING = _l('PENDING') COMPLETED = _l('COMPLETED') EXPIRED = _l('EXPIRED') def __str__(self): return '{}'.format(self.value) payment_status = [(str(_l(y)), y) for y in (PaymentStatus)] class PaymentForm(FlaskForm): status_of_payment = SelectField(_l('Payment Status'), choices=payment_status) # ... # ... 

And here is my model look like:

class Payment(db.Model): __tablename__ = 'payment' id = db.Column(db.Integer, primary_key=True) status_of_payment = db.Column(db.Enum(PaymentStatus, name='status_of_payment')) # ... # ... 

And when I try to insert the value from the Flask-WTF form to my database, I got some error.

Here is the snippet how I insert it to database:

if form.validate_on_submit(): payment = Payment( # payment_status=form.status_of_payment.data payment_status=PaymentStatus.PENDING.value # ... # ... ) 

The value of the enum PENDING also converted to the language on preferred language on my browser, so I got this error message:

sqlalchemy.exc.StatementError: (builtins.LookupError) "MENGUNGGU" is not among the defined enum values

for more information: "MENGUNGGU" = is Indonesian language for "PENDING" in English.

So the problem here is, when I insert the SelectField value, it also converts the language to my preferred browser language, and my database which is PostgreSQL block it, because I don't define the value on my enum type.

So, the point of my question is, can we excluded the i18n & l10n value from Flask-Babel when we want to insert the value to a database..?, or what should I do to face this..?

4
  • My opinion is that you should not use the translate value on the enum. It doesn't make sense to me have a internacionalizated enum, handle internacionalization in the form tier Commented Oct 2, 2019 at 15:08
  • 1
    Another shorter option would seek for a mapping from intercionalizated value to deafault language on enum class it would have something to achieve this Commented Oct 2, 2019 at 15:11
  • Have a look at my edited answer. Commented Oct 3, 2019 at 14:07
  • No, your first answer also works in my case, I'll accept the answer later while now I still experimenting on the code. Commented Oct 3, 2019 at 14:28

1 Answer 1

2

You should swap values in your choices because the first element in the tuple is the actual value that will be submitted and the second one is the presentation:

payment_status = [(y.name, _l(str(y.value))) for y in PaymentStatus]

Thanks to this you'll have translated names and proper values submitted.

Enum's name should be stored in your database instead of the value.

Sign up to request clarification or add additional context in comments.

2 Comments

I think the first answer before edited is more efficient, because we don't need to declare the _l() in each value of the enum variable. Just looping it like your first answer.
The correct answer is like this: payment_status = [(y.name, _l(str(y.value))) for y in (PaymentStatus)] swap the _l() position with str() position.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.