Reputation: 995
I'm currently stuck trying to build a variable message flashing function for my Flask forms
Since I'm building a tool that has to have multiple languages available, I wish to create custom messages for my flask form validation based on specific language input.
My form looks something like this:
class messageForm(FlaskForm):
title = StringField(
'title',
validators=[
validators.DataRequired(validationMessage('validateRequired', language=language))
]
)
the function "validationMessage" looks like this:
def validationMessage(message, language):
msg = Message.query.filter_by(title=message).first()
lang = Language.query.filter_by(abbr=language).first()
text = messageBody.query.filter_by(message_id=msg.id, language_id=lang.id).first().text
return text
As you notice, I do some lookup in a few database tables to produce my message text.
My trouble is now... How do I pass my language variable from my view to my form so that I can pass it on to the "validationMessage" function?
The language variable is based on a variable in my view endpoint
# Messages
@admin.route('/<string:language>/message', methods=['GET'])
def messageView(language='dk')
form=messageForm()
...
I have considered using my session for this, but as I understand it, I can only use this within my view and therefore not within either my form or the message function
Upvotes: 2
Views: 6331
Reputation: 5589
You can solve this problem by using the global context variable g
. The trick is not to use the builtin validator but a custom validator. The reason is that the builtin validator is a factory function. This means the validationMessage
function you pass to it will only be executed on class creation. If you build a custom validator and read the language
from the global context variable it will work.
def custom_validator(form, field):
language = g.language
msg = Message.query.filter_by(title=message).first()
lang = Language.query.filter_by(abbr=language).first()
text = messageBody.query.filter_by(message_id=msg.id, language_id=lang.id).first().text
if not len(field.data):
raise validators.ValidationError(text)
Replace the validator in your form with the custom validator:
class messageForm(FlaskForm):
title = StringField('title', validators=[custom_validator])
In the view function just create the language property for the global context variable.
# Messages
@admin.route('/<string:language>/message', methods=['GET'])
def messageView(language='dk')
g.language = language
form=messageForm()
...
Upvotes: 1