Пример #1
0
class CustomAuthForm(AuthenticationForm):
    username = forms.CharField(widget=TextInput(attrs={'class': 'input-field', 'placeholder': 'username'}))
    password = forms.CharField(
        widget=PasswordInput(attrs={'class': 'input-field', 'placeholder': 'password'}))
Пример #2
0
 def __init__(self, *args, **kwargs):
     super(UserForm, self).__init__(*args, **kwargs)
     self.fields['password'].widget = PasswordInput()
Пример #3
0
class CustomAuthenticationForm(AuthenticationForm):
    username = forms.CharField(widget=TextInput(attrs={'class': 'validate', 'placeholder': 'Username'}))
    password = forms.CharField(widget=PasswordInput(attrs={'placeholder': 'Password'}))
Пример #4
0
 class Meta:
     model = User
     fields = ['username','email','password','age','gender','icon']
     widgets = {
         'password': PasswordInput(attrs={'placeholder': '请输入密码'}, render_value=True),
     }
Пример #5
0
 class Meta:
     model = User
     #password 입력공간에 PasswordInput위젯 적용하기
     widgets = {'password': PasswordInput()}
     fields = ['username', 'password']
Пример #6
0
    class Meta:
        model = Persona
        fields = ('nombre', 'apellido', 'email', 'celular', 'usuario',
                  'region', 'contraseña', 'contraseñaconfirmar')
        widgets = {
            'nombre':
            Textarea(
                attrs={
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'id': 'nombre',
                    'class': 'form-control',
                    'required onfocus': "setVisibility('100','inline')",
                    'onBlur': "setVisibility('100','none')",
                    'onkeyup': "sync()"
                }),
            'apellido':
            Textarea(
                attrs={
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'id': 'apellido',
                    'class': "form-control",
                    'required onfocus': "setVisibility('101','inline')",
                    'onBlur': "setVisibility('101','none')"
                }),
            'email':
            EmailInput(
                attrs={
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'id': 'email',
                    'class': "form-control",
                    'required onfocus': "setVisibility('102','inline')",
                    'onBlur': "setVisibility('102','none')",
                    'type': 'email'
                }),
            'celular':
            Textarea(
                attrs={
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'id': 'celular',
                    'class': "form-control",
                    'required onfocus': "setVisibility('103','inline')",
                    'onBlur': "setVisibility('103','none')"
                }),
            'usuario':
            Textarea(
                attrs={
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'id': 'usuario',
                    'class': "form-control",
                    'required onfocus': "setVisibility('104','inline')",
                    'onBlur': "setVisibility('104','none')"
                }),
            'region':
            Select(
                attrs={
                    'class': "form-control",
                    'onfocus': "setVisibility('105','inline')",
                    'onBlur': "setVisibility('105','none')",
                    'default': "rm"
                }),
            'contraseña':
            PasswordInput(
                attrs={
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'id': 'pass',
                    'class': "form-control inputPass",
                    'required onfocus': "setVisibility('106','inline')",
                    'onBlur': "setVisibility('106','none')"
                }),
            'contraseñaconfirmar':
            PasswordInput(
                attrs={
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'id': 'passconfirm',
                    'class': "form-control",
                    'required onfocus': "setVisibility('107','inline')",
                    'onBlur': "setVisibility('107','none')"
                }),
        }

        labels = {
            'nombre': _('Nombre'),
            'apellido': _('Apellido'),
            'email': _('Correo Electronico'),
            'celular': _('Numero Telefonico'),
            'usuario': _('Usuario'),
            'region': _('Region'),
            'contraseña': _('Contraseña'),
            'contraseñaconfirmar': _('Confirmar Contraseña'),
        }
Пример #7
0
class CustomAuthForm(AuthenticationForm):
    username = forms.CharField(widget=TextInput(attrs={'class':'form-control','placeholder': '*Introduce tu nombre de usuario'}))
    password = forms.CharField(widget=PasswordInput(attrs={'class': 'form-control', 'placeholder':'*Introduce tu contraseña'}))
Пример #8
0
class LoginForm(AuthenticationForm):
    username = forms.CharField(widget=TextInput(
        attrs={'placeholder': 'Username'}))
    password = forms.CharField(widget=PasswordInput(
        attrs={'placeholder': 'Password'}))
Пример #9
0
class RegistrationForm(UserCreationForm):
    #print("entra a RegistrationForm")
    #email = forms.EmailField(required=True)
    password1 = forms.CharField(widget=PasswordInput(
        attrs={
            'class': 'validate form-control col-sm-4',
            'placeholder': 'Contraseña: Minimo 8 Caracteres'
        }))

    password2 = forms.CharField(widget=PasswordInput(
        attrs={
            'class': 'validate form-control col-sm-4',
            'placeholder': 'Confirmar Contraseña'
        }))

    class Meta:
        model = User
        fields = (
            'username',
            'name',
            'lastNameP',
            'lastNameM',
            'email',
            'date_born',
            'type_account',
            'is_superuser',
        )

        labels = {
            'username': '******',
            'name': 'Nombre ',
            'lastNameP': 'Apellido Paterno ',
            'lastNameM': 'Apellido Materno ',
            'email': 'Correo Electronico',
            'date_born': 'Fecha de Nacimiento: ',
            'type_account': 'Tipo de Cuenta',
            'is_superuser': '******'
        }

        widgets = {
            'name':
            forms.TextInput(
                attrs={
                    'class': 'validate form-control col-sm-4',
                    'placeholder': 'Introduce tu Nombre'
                }),
            'lastNameP':
            forms.TextInput(
                attrs={
                    'class': 'validate form-control col-sm-4',
                    'placeholder': 'Apellido Paterno'
                }),
            'lastNameM':
            forms.TextInput(
                attrs={
                    'class': 'validate form-control col-sm-4',
                    'placeholder': 'Apellido Materno'
                }),
            'email':
            forms.EmailInput(
                attrs={
                    'class': 'validate form-control col-sm-4',
                    'placeholder': 'Correo Ejemplo: [email protected]'
                }),
            'username':
            forms.TextInput(
                attrs={
                    'class': 'validate form-control col-sm-4',
                    'placeholder': 'Nombre de Usuario'
                }),
            'type_account':
            forms.Select(attrs={'class': 'validate form-control col-sm-4'}),
        }

    def save(self, commit=True):
        #print("entra a save)
        user = super(RegistrationForm, self).save(commit=False)

        user.username = self.cleaned_data['username']
        user.name = self.cleaned_data['name']
        user.lastNameP = self.cleaned_data['lastNameP']
        user.lastNameM = self.cleaned_data['lastNameM']
        user.email = self.cleaned_data['email']
        user.type_account = self.cleaned_data['type_account']
        user.is_superuser = self.cleaned_data['is_superuser']
        user.is_active = True
        user.date_born = timezone.now()
        user.date_joined = timezone.now()

        if commit:
            user.save()

        return user
Пример #10
0
class LoginForm(AuthenticationForm):
    # def __init__(self, *args, **kwargs):
    #     super(CustomAuthForm, self).__init__(*args, **kwargs)
    username = forms.CharField(widget=TextInput(attrs={'placeholder':'Username', 'class':'form-control'}))
    password = forms.CharField(widget=PasswordInput(attrs={'placeholder':'Password', 'class':'form-control'}))
Пример #11
0
 class Meta:
     model = User
     fields = ('username', 'password', 'first_name', 'last_name', 'email')
     widgets = {'password': PasswordInput()}
Пример #12
0
class LoginForm(AuthenticationForm):
    username = forms.CharField(label='', widget=TextInput(attrs={'class': 'form-control', 'placeholder': 'Username'}))
    password = forms.CharField(label='',
                               widget=PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password'}))
Пример #13
0
class CustomAuthenticationForm(AuthenticationForm):
	username = forms.CharField(widget=TextInput(attrs={'class': 'form-control','placeholder': _('Username')}))
	password = forms.CharField(widget=PasswordInput(attrs={'class': 'form-control','placeholder':_('Password')}))
Пример #14
0
class UserRegisterForm(forms.ModelForm):
    email = forms.EmailField(label='Email Address',
                             widget=EmailInput(
                                 attrs={
                                     'id': 'your-email',
                                     'class': 'input-text',
                                     'placeholder': "Email Address"
                                 }))
    email2 = forms.EmailField(label='Confirm Email',
                              widget=EmailInput(
                                  attrs={
                                      'id': 'your-email',
                                      'class': 'input-text',
                                      'placeholder': "Confirm Email Address"
                                  }))
    password = forms.CharField(widget=PasswordInput(
        attrs={
            'id': "password",
            'class': 'input-text',
            'placeholder': "Password"
        }))
    password1 = forms.CharField(widget=PasswordInput(
        attrs={
            'id': "password1",
            'class': 'input-text',
            'placeholder': "Confirm Password"
        }))
    username = forms.CharField(
        label='Username',
        help_text="",
        widget=forms.TextInput(attrs={
            'id': "full-name",
            'class': "input-text",
            'placeholder': "Username"
        }))

    class Meta:
        model = User
        feilds = ['email', 'email2', 'username', 'password']
        exclude = [
            'first_name', 'last_name', 'groups', 'user_permissions',
            'is_staff', 'is_active', 'is_superuser', 'last_login',
            'date_joined'
        ]

    field_order = ['username', 'email', 'email2', 'password']

    def clean(self, *args, **kwargs):
        email = self.cleaned_data.get('email')
        email2 = self.cleaned_data.get('email2')
        if email != email2:
            raise forms.ValidationError("Emails must match")
        email_qs = User.objects.filter(email=email)
        if email_qs.exists():
            raise forms.ValidationError(
                "This email has already been registered")
        password = self.cleaned_data.get('password')
        password1 = self.cleaned_data.get('password1')
        if password != password1:
            raise forms.ValidationError('Passwords must match')
        if len(password) > 15:
            raise forms.ValidationError('Password must be less than 15 chars')
        return super(UserRegisterForm, self).clean(*args, **kwargs)
Пример #15
0
class CustomAuthForm(AuthenticationForm):
    # Inherited fields:
    # username
    # password
    username = forms.CharField(widget=TextInput(attrs={'class':'form-control', 'placeholder': 'Email'}))
    password = forms.CharField(widget=PasswordInput(attrs={'class': 'form-control', 'placeholder':'Password'}))
Пример #16
0
class CommCareAccountForm(forms.Form):
    """
    Form for CommCareAccounts
    """
    username = forms.CharField(required=True)
    password_1 = forms.CharField(label=ugettext_lazy('Password'),
                                 widget=PasswordInput(),
                                 required=True,
                                 min_length=1)
    password_2 = forms.CharField(label=ugettext_lazy('Password (reenter)'),
                                 widget=PasswordInput(),
                                 required=True,
                                 min_length=1)
    phone_number = forms.CharField(max_length=80,
                                   required=False,
                                   help_text=ugettext_lazy(
                                       "Please enter number, including "
                                       "international code, in digits only."))

    def __init__(self, *args, **kwargs):
        if 'domain' not in kwargs:
            raise Exception('Expected kwargs: domain')
        self.domain = kwargs.pop('domain', None)
        super(forms.Form, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.label_class = 'col-lg-3'
        self.helper.field_class = 'col-lg-9'
        self.helper.layout = Layout(
            Fieldset(
                _("Mobile Worker's Primary Information"),
                'username',
                'password_1',
                'password_2',
                'phone_number',
            ))

    def clean_username(self):
        return clean_mobile_worker_username(self.domain,
                                            self.cleaned_data.get('username'))

    def clean_phone_number(self):
        phone_number = self.cleaned_data['phone_number']
        phone_number = re.sub(r'\s|\+|\-', '', phone_number)
        if phone_number == '':
            return None
        elif not re.match(r'\d+$', phone_number):
            raise forms.ValidationError(
                _("%s is an invalid phone number." % phone_number))
        return phone_number

    def clean(self):
        try:
            password_1 = self.cleaned_data['password_1']
            password_2 = self.cleaned_data['password_2']
        except KeyError:
            pass
        else:
            if password_1 != password_2:
                raise forms.ValidationError("Passwords do not match")

        return self.cleaned_data
Пример #17
0
class CustomAuthForm(AuthenticationForm):
    username = forms.CharField(widget=forms.TextInput(
        attrs={"placeholder": "username"}))
    password = forms.CharField(widget=PasswordInput(
        attrs={"placeholder": "Password"}))
Пример #18
0
class FrontAuthForm(AuthenticationForm):
   username = forms.CharField()
   password = forms.CharField(widget=PasswordInput())
Пример #19
0
    class meta:
        model = User
        fields = ('username', 'email', 'first_name', 'last_name', 'password1',
                  'password2')

        widgets = {
            'first_name':
            Textarea(
                attrs={
                    'id': 'first_name',
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'class': 'form-control',
                    'required onfocus': "setVisibility('100','inline')",
                    'onBlur': "setVisibility('100','none')"
                }),
            'last_name':
            Textarea(
                attrs={
                    'id': 'last_name',
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'class': "form-control",
                    'required onfocus': "setVisibility('101','inline')",
                    'onBlur': "setVisibility('101','none')"
                }),
            'email':
            EmailInput(
                attrs={
                    'id': 'useremail',
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'class': "form-control",
                    'required onfocus': "setVisibility('102','inline')",
                    'onBlur': "setVisibility('102','none')",
                    'type': 'email'
                }),
            'username':
            Textarea(
                attrs={
                    'id': 'username',
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'class': "form-control",
                    'required onfocus': "setVisibility('104','inline')",
                    'onBlur': "setVisibility('104','none')"
                }),
            'password1':
            PasswordInput(
                attrs={
                    'id': 'password1',
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'class': "form-control inputPass",
                    'required onfocus': "setVisibility('106','inline')",
                    'onBlur': "setVisibility('106','none')"
                }),
            'password2':
            PasswordInput(
                attrs={
                    'id': 'password2',
                    'rows': 1,
                    'cols': 30,
                    'style': 'resize:none;',
                    'class': "form-control",
                    'required onfocus': "setVisibility('107','inline')",
                    'onBlur': "setVisibility('107','none')"
                }),
        }

        labels = {
            'first_name': _('first_name'),
        }
Пример #20
0
 class Meta:
     model = User
     widgets = {'password': PasswordInput()}
     fields = ['username', 'password']
Пример #21
0
class RegisterForm(CustomModelForm):
    autofocus_post_clean = True

    class Meta:
        model = Account
        fields = ['name', 'password', 'password_repeat', 'email']

    name = CharField(
        autofocus=True,
        label=_('Account name'),
        placeholder=_('Type your account name here'),
        help_text=Account._meta.get_field('name').help_text,
        min_length=GetSetting('INPUT_USERNAME_MIN_LENGTH'),
        max_length=GetSetting('INPUT_USERNAME_MAX_LENGTH'),
        widget=TextInput(),
    )

    password = CharField(
        label=_('Password'),
        placeholder=_('Type your password here'),
        help_text=Account._meta.get_field('password').help_text,
        min_length=GetSetting('INPUT_PASSWORD_MIN_LENGTH'),
        max_length=GetSetting('INPUT_PASSWORD_MAX_LENGTH'),
        widget=PasswordInput(),
    )

    password_repeat = CharField(
        label=_('Repeat password'),
        placeholder=_('Repeat your password here'),
        help_text=_('This password needs to match above.'),
        min_length=GetSetting('INPUT_PASSWORD_MIN_LENGTH'),
        max_length=GetSetting('INPUT_PASSWORD_MAX_LENGTH'),
        widget=PasswordInput(),
    )

    email = EmailField(
        label=_('Email address'),
        placeholder=_('Type your email address here'),
        help_text=Account._meta.get_field('email').help_text,
        widget=EmailInput(),
    )

    def save(self, commit=True):
        self.instance = Account.objects.create_account(
            name=self.cleaned_data.get('name'),
            password=self.cleaned_data.get('password'),
            email=self.cleaned_data.get('email'))
        return self.instance

    def clean(self):
        super(RegisterForm, self).clean()

        password = self.cleaned_data.get('password')
        password_repeat = self.cleaned_data.get('password_repeat')

        try:
            validate_password(password)
        except ValidationError as e:
            self.add_error('password', e.messages)

        if password != password_repeat:
            self.add_error('password_repeat',
                           _('You didn\'t repeat your password correctly.'))

        return self.cleaned_data
Пример #22
0
class SelfRegistrationForm(forms.Form):

    def __init__(self, *args, **kwargs):
        if 'domain' not in kwargs:
            raise Exception('Expected kwargs: domain')
        self.domain = kwargs.pop('domain')
        require_email = kwargs.pop('require_email', False)

        super(SelfRegistrationForm, self).__init__(*args, **kwargs)

        if require_email:
            self.fields['email'].required = True

        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-xs-4'
        self.helper.field_class = 'col-xs-8'
        layout_fields = [
            crispy.Fieldset(
                _('Register'),
                crispy.Field('username', placeholder='sam123'),
                crispy.Field('password'),
                crispy.Field('password2'),
                crispy.Field('email'),
            ),
            hqcrispy.FormActions(
                StrictButton(
                    _('Register'),
                    css_class='btn-primary',
                    type='submit',
                )
            ),
        ]
        self.helper.layout = crispy.Layout(*layout_fields)

    username = TrimmedCharField(
        required=True,
        label=ugettext_lazy('Create a Username'),
    )
    password = forms.CharField(
        required=True,
        label=ugettext_lazy('Create a Password'),
        widget=PasswordInput(),
    )
    password2 = forms.CharField(
        required=True,
        label=ugettext_lazy('Re-enter Password'),
        widget=PasswordInput(),
    )
    email = forms.EmailField(
        required=False,
        label=ugettext_lazy('Email address (used for tasks like resetting your password)'),
    )

    def clean_username(self):
        return clean_mobile_worker_username(
            self.domain,
            self.cleaned_data.get('username')
        )

    def clean_password2(self):
        if self.cleaned_data.get('password') != self.cleaned_data.get('password2'):
            raise forms.ValidationError(_('Passwords do not match.'))
Пример #23
0
class CommCareAccountForm(forms.Form):
    """
    Form for CommCareAccounts
    """
    # 128 is max length in DB
    # 25 is domain max length
    # @{domain}.commcarehq.org adds 16
    # left over is 87 and 80 just sounds better
    max_len_username = 80

    username = forms.CharField(max_length=max_len_username, required=True)
    password = forms.CharField(
        widget=PasswordInput(),
        required=True,
        min_length=1,
        help_text="Only numbers are allowed in passwords")
    password_2 = forms.CharField(label='Password (reenter)',
                                 widget=PasswordInput(),
                                 required=True,
                                 min_length=1)
    domain = forms.CharField(widget=HiddenInput())
    phone_number = forms.CharField(max_length=80, required=False)

    class Meta:
        app_label = 'users'

    def __init__(self, *args, **kwargs):
        super(forms.Form, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
            Fieldset(
                'Create new Mobile Worker account', 'username', 'password',
                HTML("{% if only_numeric %}"
                     "<div class=\"control-group\"><div class=\"controls\">"
                     "To enable alphanumeric passwords, go to the "
                     "applications this user will use, go to CommCare "
                     "Settings, and change Password Format to Alphanumeric."
                     "</div></div>"
                     "{% endif %}"), 'password_2', 'phone_number',
                Div(Div(HTML(
                    "Please enter number, including international code, in digits only."
                ),
                        css_class="controls"),
                    css_class="control-group")),
            FormActions(
                ButtonHolder(
                    Submit(
                        'create',
                        'Create Mobile Worker',
                        css_id='submit_mobile_worker',
                    ))))

    def clean_phone_number(self):
        phone_number = self.cleaned_data['phone_number']
        phone_number = re.sub('\s|\+|\-', '', phone_number)
        if phone_number == '':
            return None
        elif not re.match(r'\d+$', phone_number):
            raise forms.ValidationError(
                _("%s is an invalid phone number." % phone_number))
        return phone_number

    def clean_username(self):
        username = self.cleaned_data['username']
        if username == 'admin' or username == 'demo_user':
            raise forms.ValidationError(
                "The username %s is reserved for CommCare." % username)
        return username

    def clean(self):
        try:
            password = self.cleaned_data['password']
            password_2 = self.cleaned_data['password_2']
        except KeyError:
            pass
        else:
            if password != password_2:
                raise forms.ValidationError("Passwords do not match")
            if self.password_format == 'n' and not password.isnumeric():
                raise forms.ValidationError("Password is not numeric")

        try:
            username = self.cleaned_data['username']
        except KeyError:
            pass
        else:
            if len(username) > CommCareAccountForm.max_len_username:
                raise forms.ValidationError(
                    "Username %s is too long.  Must be under %d characters." %
                    (username, CommCareAccountForm.max_len_username))
            validate_username('*****@*****.**' % username)
            domain = self.cleaned_data['domain']
            username = format_username(username, domain)
            num_couch_users = len(
                CouchUser.view("users/by_username", key=username))
            if num_couch_users > 0:
                raise forms.ValidationError("CommCare user already exists")

            # set the cleaned username to [email protected]
            self.cleaned_data['username'] = username
        return self.cleaned_data
Пример #24
0
class UserForm(forms.ModelForm):
    password = forms.CharField(widget=PasswordInput())

    class Meta:
        model = User
        fields = ('username', 'email', 'password')
Пример #25
0
class CustomAuthForm(AuthenticationForm):
    username = forms.CharField(
        widget=TextInput(attrs={'placeholder': '*****@*****.**'}), label='')
    password = forms.CharField(
        widget=PasswordInput(attrs={'placeholder': 'password'}), label='')
Пример #26
0
class LoginForm(Form):
    username = forms.CharField(widget=TextInput(
        attrs={'class': 'form-control'}))
    password = forms.CharField(widget=PasswordInput(
        attrs={'class': 'form-control'}))
Пример #27
0
class PlaceholderAuthForm(AuthenticationForm):
    username = forms.CharField(widget=TextInput(
        attrs={'placeholder': 'Логин'}))
    password = forms.CharField(widget=PasswordInput(
        attrs={'placeholder': 'Пароль'}))
Пример #28
0
        _("The port on which your SMTP server is listening to. Usually this is 25, but can be something else."
          ),
        required=False))

EMAIL_HOST_USER = Setting(
    'EMAIL_HOST_USER', '', EMAIL_SET,
    dict(label=_("Email User"),
         help_text=_("The username for your SMTP connection."),
         required=False))

EMAIL_HOST_PASSWORD = Setting(
    'EMAIL_HOST_PASSWORD', '', EMAIL_SET,
    dict(label=_("Email Password"),
         help_text=_("The password for your SMTP connection."),
         required=False,
         widget=PasswordInput(render_value=True)))

EMAIL_USE_TLS = Setting(
    'EMAIL_USE_TLS', False, EMAIL_SET,
    dict(label=_("Use TLS"),
         help_text=_(
             "Whether to use TLS for authentication with your SMTP server."),
         required=False))

DEFAULT_FROM_EMAIL = Setting(
    'DEFAULT_FROM_EMAIL', '', EMAIL_SET,
    dict(
        label=_("Site 'from' Email Address"),
        help_text=
        _("The address that will show up on the 'from' field on emails sent by your website."
          ),
Пример #29
0
class CustomSetPasswordForm(SetPasswordForm):
    new_password1 = forms.CharField(widget=PasswordInput(attrs={'placeholder': 'New password'}))
    new_password2 = forms.CharField(widget=PasswordInput(attrs={'placeholder': 'Repeat password'}))
Пример #30
0
class SignUpForm(UserCreationForm):

    username = CharField(
        label="Username",
        widget=TextInput(attrs={
            "class": "show-requirements",
            "data-requirement": "required"
        }),
        error_messages={
            "required": REQUIRED_ERROR.format("username"),
            "unique": "Username invalid. Please try another.",
        },
    )
    password1 = CharField(
        min_length=settings.PASSWORD_MIN_LENGTH,
        max_length=settings.PASSWORD_MAX_LENGTH,
        label="Password",
        widget=PasswordInput(
            attrs={
                "class": "show-requirements",
                "data-requirement": "password",
                "autocomplete": "off"
            }),
        error_messages={"required": REQUIRED_ERROR.format("password")},
    )
    password2 = CharField(
        widget=PasswordInput(
            attrs={
                "class": "show-requirements",
                "data-requirement": "password-confirmation",
                "autocomplete": "off",
            }),
        label="Confirm password",
        error_messages={
            "required": REQUIRED_ERROR.format("password confirmation")
        },
    )
    email = forms.EmailField(
        required=False,
        label="Optional email",
        help_text=mark_safe("""
            Your email is only used to reset your password if you lose it.
        """),
    )
    terms = forms.BooleanField(
        required=True,
        label=mark_safe("""
            I have read and agree to Callisto\'s Terms and Privacy Policy
        """),
        help_text=mark_safe("""
            We care deeply about your privacy, and know you do too.
            Your information will remain completely private until you choose otherwise.
            Read more in Callisto's
            <a href="/about/our-policies/#terms-of-service" target="_blank">
            Terms</a> and
            <a href="/about/our-policies/#privacy-policy" target="_blank">
            Privacy Policy</a>.
        """),
        error_messages={"required": TERMS_NOT_ACCEPTED_ERROR},
    )

    class Meta:
        model = User
        fields = ("username", "password1", "password2", "email")