Yaroslav
Yaroslav

Reputation: 31

How to fix "The CSRF token is missing" in Flask-WTForms

I'm creating a small corporate web-portal. There will be computers database which contains information about all the computers in a company. I'm creating a WTForm for editing computers' properties. I have a page with a table that contains the computers' properties. There are special buttons on every row. When a user presses one of them, I want to show a page with the form with default values taken from the database. When I edit defaults in a View function, I get an error:

The CSRF token is missing.

My View function:

def edit_computer(computer_id):
    if admin_can() or sysadmin_can():
        computer = models.Computer.query.filter_by(id=computer_id).one()
        user = models.User.query.filter_by(id=computer.user_id).one()
        email = user.email

        form = forms.EditComputerForm()
        form.email.default = user.email
        form.type_.default=computer.type_
        form.model.default = computer.model
        form.cpu.default = computer.cpu
        form.ram.default = computer.ram
        form.rom.default = computer.rom
        form.os.default = computer.os
        form.supplements.default = computer.supplements
        form.process()

        if form.validate_on_submit():
            ...

When I don't set defaults (remove this ↓), the code works fine

form.email.default = user.email
form.type_.default=computer.type_
form.model.default = computer.model
form.cpu.default = computer.cpu
form.ram.default = computer.ram
form.rom.default = computer.rom
form.os.default = computer.os
form.supplements.default = computer.supplements
form.process()

Form:

class EditComputerForm(FlaskForm):    
    email = EmailField("Owner's E-Mail",
                       validators=[DataRequired(), Email()])
    type_ = SelectField('type',
                        choices=[('Notebook', 'Notebook'), ('PC', 'PC')])
    model = StringField('Model')
    cpu = StringField('CPU')
    ram = StringField('RAM')
    rom = StringField('ROM')
    os = StringField('OS')
    supplements = TextAreaField('Supplements')
    submit = SubmitField('Edit')

HTML:

{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}

{% block app_content %}
<h3>Edit computer's properties {{ add_title }}</h3>
<hr>
{{ wtf.quick_form(form, button_map={'submit': 'primary'}) }}
{% endblock %}

{% block app_windows %}{% endblock %}

How to fix this error? WTForm isn't working now.

Upvotes: 3

Views: 842

Answers (1)

RushK
RushK

Reputation: 555

It's the form.process() that ruins the csrf process.

To set form values dynamically, I suggest you do use the data attribute, not the default attribute. Then you don't have to call form.process().

form.email.data= user.email
form.type_.data=computer.type_
form.model.data= computer.model
form.cpu.data= computer.cpu
form.ram.data= computer.ram
form.rom.data= computer.rom
form.os.data= computer.os
form.supplements.data= computer.supplements

Upvotes: 5

Related Questions