Source code for accounts.forms
# coding: utf-8
from datetime import date, datetime
from annoying.functions import get_object_or_None
from django import forms
from django.core import validators
from django.conf import settings
from django.contrib.auth.models import User
from django.forms import ModelForm
from app.shared.forms import SelectDateWidgetWithNone
from .models import (
UserActivation,
UserProfile,
)
# -----------------------------------------------------------------------------
# Mixins
# -----------------------------------------------------------------------------
[docs]class CheckCurrentPasswordMixin(forms.Form):
current_password = forms.CharField(
max_length=30,
required=True,
widget=forms.PasswordInput,
label='Password'
)
[docs] def clean_current_password(self):
current_password = self.cleaned_data.get('current_password')
if not self.request.user.check_password(current_password):
raise forms.ValidationError('Password is incorrect')
return current_password
[docs]class EmailMixin(forms.Form):
email = forms.EmailField(
max_length=50, required=True
# error_messages={
# 'invalid': 'Enter a valid email address',
# 'required': 'Enter email address'
# }
)
[docs] def clean_email(self):
email = self.cleaned_data.get('email')
# get activation objects for this email
activation = get_object_or_None(UserActivation, user__email=email)
# check if activation time has expired
if activation:
created_at = activation.created_at.replace(tzinfo=None)
timedelta = datetime.now() - created_at
if timedelta.days > settings.ACCOUNT_ACTIVATION_DAYS:
user = activation.user
activation.delete()
user.delete()
if email and User.objects.filter(email=email):
raise forms.ValidationError('This email is already taken.')
return email
[docs]class SetNewPasswordFormMixin(forms.Form):
password = forms.CharField(
validators=[validators.MinLengthValidator(5)],
max_length=30,
required=True,
widget=forms.PasswordInput,
label='New password',
error_messages={
'min_length': 'The password must be at least 5 characters long.'
}
)
re_password = forms.CharField(
max_length=30,
required=True,
widget=forms.PasswordInput,
label='Retype new password',
)
[docs] def clean_re_password(self):
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('re_password')
if password != re_password:
raise forms.ValidationError('Passwords doesn\'t match')
return re_password
[docs]class UsernameOrEmailMixin(forms.Form):
username_or_email = forms.CharField(
max_length=50, label=u"Username or email", required=True)
[docs] def clean_username_or_email(self):
username_or_email = self.cleaned_data.get('username_or_email')
# check, if input in email or username
if username_or_email.find('@') >= 0:
# email
user = get_object_or_None(User, email=username_or_email)
if not user:
raise forms.ValidationError('This email is already taken.')
else:
# username
user = get_object_or_None(User, username=username_or_email)
if not user:
raise forms.ValidationError(
'User with this username doesn\'t exist.')
return username_or_email
# -----------------------------------------------------------------------------
# Forms
# -----------------------------------------------------------------------------
[docs]class LoginForm(forms.Form):
username = forms.CharField(max_length=30, required=True)
password = forms.CharField(
max_length=30,
required=True,
widget=forms.PasswordInput,
)
[docs]class RegistrationForm(EmailMixin):
username = forms.SlugField(
validators=[validators.MinLengthValidator(3)],
max_length=30,
required=True,
label='Username',
error_messages={
'min_length': 'Username is too short (at least 3 chars).'
},
)
password = forms.CharField(
validators=[validators.MinLengthValidator(5)],
max_length=30,
required=True,
widget=forms.PasswordInput,
error_messages={
'invalid': 'Username can only contain letters, '
'numbers and signs _ + @ .-',
'min_length': 'Password is too short (at least 5 chars).'
},
)
re_password = forms.CharField(
max_length=30,
required=True,
widget=forms.PasswordInput,
label='Retype password',
)
rules = forms.BooleanField(required=True, label='I accept the terms')
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(RegistrationForm, self).__init__(*args, **kwargs)
key_order = ['username', 'email', 'password', 're_password', 'rules']
self.fields.keyOrder = key_order
[docs] def clean_re_password(self):
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('re_password')
if password != re_password:
raise forms.ValidationError('Passwords doesn\'t match')
return re_password
[docs] def clean_username(self):
username = self.cleaned_data.get('username')
if username and User.objects.filter(username=username):
raise forms.ValidationError(
'This username is already taken.')
return username
[docs]class ResendActivationMailForm(UsernameOrEmailMixin):
[docs] def clean_username_or_email(self):
username_or_email = self.cleaned_data.get('username_or_email')
user = get_object_or_None(User, username=username_or_email) or \
get_object_or_None(User, email=username_or_email)
# check, if account is already activated
if user and user.is_active:
raise forms.ValidationError('Account is already activated')
# check, if old activation link is used
if user and not get_object_or_None(UserActivation, user=user):
raise forms.ValidationError('Activation link is incorrect')
return super(ResendActivationMailForm, self).clean_username_or_email()
[docs]class ChangePasswordForm(SetNewPasswordFormMixin):
old_password = forms.CharField(
max_length=30,
required=True,
widget=forms.PasswordInput,
label='Current password',
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(ChangePasswordForm, self).__init__(*args, **kwargs)
self.fields.keyOrder = ['old_password', 'password', 're_password']
[docs] def clean_old_password(self):
old_password = self.cleaned_data.get('old_password')
if not self.request.user.check_password(old_password):
raise forms.ValidationError('Password is incorrect.')
return old_password
[docs]class ChangeEmailForm(CheckCurrentPasswordMixin, EmailMixin):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(ChangeEmailForm, self).__init__(*args, **kwargs)
self.fields.keyOrder = ['email', 'current_password']
[docs]class UserProfileForm(ModelForm):
dob = forms.DateField(widget=SelectDateWidgetWithNone(
years=(lambda y=date.today().year: range(y, y - 150, -1))(),
attrs={'class': 'form-control dob-field'}),
required=False,
label=u"Date of birth",
)
[docs] class Meta:
model = UserProfile
exclude = ('user',)
name = 'Profile settings'
button_text = 'Save'
[docs] def clean_dob(self):
dob = self.cleaned_data.get('dob')
if dob and not date.today() > dob:
raise forms.ValidationError(
'Are you time traveller, or something?')
return dob
[docs] def clean_height(self):
height = self.cleaned_data.get('height')
if height and not 30 < height < 300:
raise forms.ValidationError('Are you really %s cm tall?' % height)
return height