1

I am trying to make a registration page in my Flask application. I am using Flask-Security for user management. I have set it up properly; the standard registration page did render correctly. However, my model consists of quite a few extra, required fields, so I needed to update the view.

My security_config file looks as follows:

from models import *
from flask_security.forms import ConfirmRegisterForm, Required

class ExtendedConfirmRegisterForm(ConfirmRegisterForm):
    first_name = CharField('Voornaam', [Required()])
    last_name = CharField('Achternaam', [Required()])        

# Setup Flask-Security
user_datastore = PeeweeUserDatastore(db, Student, Role, StudentRoleRel)
security = Security(app, user_datastore,
         confirm_register_form=ExtendedConfirmRegisterForm)

My form:

{% extends "base.html" %}
{% from "security/_macros.html" import render_field_with_errors, render_field %}
{% include "security/_messages.html" %}
{% block main%}
<h1>Registreer</h1>
<form action="{{ url_for_security('register') }}" method="POST" name="register_user_form">
  {{ register_user_form.hidden_tag() }}
  {{ render_field(register_user_form.first_name) }}
  {{ render_field(register_user_form.last_name) }}
  {{ render_field_with_errors(register_user_form.email) }}
  {{ render_field_with_errors(register_user_form.password) }}
  {% if register_user_form.password_confirm %}
    {{ render_field_with_errors(register_user_form.password_confirm) }}
  {% endif %}
  {{ render_field(register_user_form.submit) }}
</form>
{% endblock %}

When I try to open the register page, I get the following error:

AttributeError: 'CharField' object has no attribute '__call__'

I don't really know how to proceed. How can I resolve this issue?

Ben
  • 1,561
  • 4
  • 21
  • 33

2 Answers2

1

I found the problem myself.

In my security config file, I forgot to import TextField (in the original, I used CharField, but this type is unavailable)

from models import *
from flask_security.forms import ConfirmRegisterForm, Required, TextField

class ExtendedConfirmRegisterForm(ConfirmRegisterForm):
    first_name = TextField('Voornaam', [Required()])
    last_name = TextField('Achternaam', [Required()])        

# Setup Flask-Security
user_datastore = PeeweeUserDatastore(db, Student, Role, StudentRoleRel)
security = Security(app, user_datastore,
         confirm_register_form=ExtendedConfirmRegisterForm)
Ben
  • 1,561
  • 4
  • 21
  • 33
  • this throws `InterfaceError: Error binding parameter 0 - probably unsupported type` – KJW May 06 '14 at 07:33
  • 1
    hey I am getting `jinja2.exceptions.UndefinedError: 'flask_security.forms.ConfirmRegisterForm object' has no attribute 'first_name'` – user299709 Feb 18 '15 at 06:09
  • @user299709 did you ever work around this? I am having the same problem. – Jeff Bluemel Apr 08 '18 at 23:05
  • 1
    @JeffB. I found the problem was with the context processor decorator. In the original response OP used "confirm_register_form", whereas for the register page you should use "register_form" when instantiating the security object. Full details can be found here: https://flask-security.readthedocs.io/en/latest/customizing.html – tpgmartin Aug 18 '19 at 21:25
1

If you are getting something like: jinja2.exceptions.UndefinedError: 'flask_security.forms.ConfirmRegisterForm object' has no attribute 'first_name'

Then it is likely due to SECURITY_CONFIRMABLE, you set that to true which means flask will use a different form. More details: https://github.com/mattupstate/flask-security/issues/54

olive_tree
  • 1,417
  • 16
  • 23