I have some fields in page disabled as for example:(using jinja2 templating system)
<html>
<body>
<form action="" method=POST>
{{ form.name(disabled=True) }}
{{ form.title }}
-- submit button --
</form>
</body>
</html>
Field is disabled in the form as expected.
In my views.py: On doing validate_on_submit() on form submit, it fails with validation error on 'name' field which is disabled. I was hoping that validation ignores disabled field. Is it the right behaviour? If so, can you please let know how to handle such a case?
Updated:
class TeamForm(wtf.Form):
name = wtf.TextField("Team Name", validators=[validators.Required()])
title = wtf.TextField("Title", validators=[validators.Required()])
You can perform this type of form validation by using the CompareValidator control. To compare two dates, you need to set the ControlToValidate, ControlToCompare, Operator, and Type properties of the CompareValidator control.
String field theory (SFT) is a formalism in string theory in which the dynamics of relativistic strings is reformulated in the language of quantum field theory.
The form. hidden_tag() template argument generates a hidden field that includes a token that is used to protect the form against CSRF attacks. All you need to do to have the form protected is include this hidden field and have the SECRET_KEY variable defined in the Flask configuration.
This is actually an interesting problem, and the way WTForms solves it is intentionally something that requires explicitness, because it has to do with security and not allowing users to fake input.
So the intent is, that "managers" cannot edit the name, while "admins" can.
At first glance this seems obvious, just disable the field in HTML, and write your view like this:
def edit_team():
form = TeamForm(request.POST, obj=team)
if request.POST and form.validate():
form.populate_obj(team) # <-- This is the dangerous part here
return redirect('/teams')
return render('edit_team.html')
As written, this is a major security risk, because the disabled property in HTML forms is client-side only. Anyone with an HTML inspector (ie FireBug, webkit document inspector, etc) can remove this property, or someone could simply make a request like so:
POST /edit_team/7 HTTP/1.0
Content-Type: application/x-urlencoded
team=EVILTEAMNAME&title=foo
The issue then is of course, how do we gate this properly on the server-side, corresponding to the appropriate way of doing this? The correct approach with WTForms is to not have the field in the first place. There's a few ways to do this, one is to use form composition and have e.g. ManagerTeamForm and AdminTeamForm (sometimes this is better) but other times it's easier to use del to remove specific fields.
So here's how you would write your view, and not have the validation issues:
def edit_team():
form = TeamForm(request.POST, obj=team)
if user.role == 'manager':
del form.name
if request.POST and form.validate():
form.populate_obj(team)
return redirect('/teams')
return render('edit_team.html')
And a quick modification to the template:
<html>
<body>
<form action="" method=POST>
{% if 'name' in form %}
{{ form.name() }}
{% else %}
{{ team.name|e }}
{% endif %}
{{ form.title }}
-- submit button --
</form>
</body>
</html>
Some pieces of reference for wtforms best-practices:
You need to make the name field optional when defining the form.
name = wtf.TextField("Team Name", validators=[validators.Optional()])
Then in your views, pass a variable called "role" and set it to either manager or admin depending on the user.
<form action="" method=POST>
{% if role == 'manager' % }
{{ form.name(disabled=True) }}
{% else % }
{{ form.name() }}
{{ form.title }}
-- submit button --
</form>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With