/signup page works and validates correctly
This commit is contained in:
parent
03ba297122
commit
d48cf18566
18
signup/forms.py
Normal file
18
signup/forms.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Form(s) for the signup app.
|
||||||
|
"""
|
||||||
|
from django import forms
|
||||||
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
|
|
||||||
|
from users.models import User
|
||||||
|
|
||||||
|
class SignupForm(UserCreationForm):
|
||||||
|
"""
|
||||||
|
The form for the signup page.
|
||||||
|
"""
|
||||||
|
email = forms.EmailField(max_length=254, help_text="Must be a valid email address.")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ('username', 'email', 'password1', 'password2')
|
|
@ -1,24 +1,10 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}Sign up a new account{% endblock %}
|
{% block title %}Sign up a new account{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Sign up</h1>
|
<h1>Sign up</h1>
|
||||||
<div id="namePassRules">
|
<form method="post" action="{{ url('signup:index') }}">
|
||||||
<p>Username rules:
|
{{ csrf_input }}
|
||||||
<ul>
|
{{ form.as_p() }}
|
||||||
<li>Must be between 3 and 20 characters</li>
|
<input type="submit" value="Sign up" name="submit"/>
|
||||||
<li>Can only contain ASCII letters (case sensitive) and numbers</li>
|
</form>
|
||||||
</ul>
|
|
||||||
<p>Password rules:
|
|
||||||
<ul>
|
|
||||||
<li>Must be between 8 and 1024 characters</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<form method="post" action="{{ url('signup:index') }}">
|
|
||||||
{{ csrf_input }}
|
|
||||||
<input type="text" placeholder="Username" name="username" maxlength="20" required/><br />
|
|
||||||
<input type="text" placeholder="Email" name="email" maxlength="20" required/><br />
|
|
||||||
<input type="password" placeholder="Password" name="password" maxlength="1024" required/><br />
|
|
||||||
<input type="password" placeholder="Verify password" name="password_verify" maxlength="1024" required/><br />
|
|
||||||
<input type="submit" value="Sign up" name="submit"/>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
"""
|
"""
|
||||||
/signup app views.
|
/signup app views.
|
||||||
"""
|
"""
|
||||||
|
# TODO: make unique username validation be case insensitive
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
|
|
||||||
from users.models import User
|
from .forms import SignupForm
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
"""
|
"""
|
||||||
|
@ -12,7 +13,11 @@ def index(request):
|
||||||
"""
|
"""
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
return redirect('homepage:index')
|
return redirect('homepage:index')
|
||||||
if request.method == "GET":
|
if request.method == 'POST':
|
||||||
context = {}
|
form = SignupForm(request.POST)
|
||||||
return render(request, 'signup/index.html', context)
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
return redirect('login:index')
|
||||||
|
else:
|
||||||
|
form = SignupForm()
|
||||||
|
return render(request, 'signup/index.html', {'form': form})
|
||||||
|
|
|
@ -98,9 +98,6 @@ DATABASES = {
|
||||||
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
|
||||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
|
@ -108,11 +105,11 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
'NAME': 'users.validators.MaximumLengthValidator',
|
||||||
},
|
'OPTIONS': {
|
||||||
{
|
'max_length': 1024,
|
||||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
}
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,9 +120,9 @@ LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
TIME_ZONE = 'America/New_York'
|
TIME_ZONE = 'America/New_York'
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = False
|
||||||
|
|
||||||
USE_L10N = True
|
USE_L10N = False
|
||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
|
@ -2,29 +2,44 @@
|
||||||
"""
|
"""
|
||||||
A custom user model.
|
A custom user model.
|
||||||
"""
|
"""
|
||||||
|
import string
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.core.validators import MinLengthValidator, MaxLengthValidator
|
||||||
from django.contrib.auth.validators import UnicodeUsernameValidator
|
|
||||||
|
from .validators import CharValidator
|
||||||
|
|
||||||
class User(AbstractUser):
|
class User(AbstractUser):
|
||||||
"""
|
"""
|
||||||
A custom user model.
|
A custom user model.
|
||||||
"""
|
"""
|
||||||
username_validator = UnicodeUsernameValidator()
|
username_char = CharValidator(
|
||||||
|
string.ascii_letters + string.digits,
|
||||||
|
"Username must only contain alphanumeric characters."
|
||||||
|
)
|
||||||
|
username_min = MinLengthValidator(
|
||||||
|
3,
|
||||||
|
"Username must contain more than 3 characters."
|
||||||
|
)
|
||||||
|
username_max = MaxLengthValidator(
|
||||||
|
20,
|
||||||
|
"Username must contain less than 20 characters."
|
||||||
|
)
|
||||||
username = models.CharField(
|
username = models.CharField(
|
||||||
_('username'),
|
'username',
|
||||||
max_length=20,
|
max_length=20,
|
||||||
unique=True,
|
unique=True,
|
||||||
help_text=_("Required. 20 characters or fewer. "
|
help_text="Must be between 3 and 20 characters. " \
|
||||||
+ "Letters, digits and @/./+/-/_ only."),
|
+ "Letters and digits only.",
|
||||||
validators=[username_validator],
|
validators=[username_char, username_min, username_max],
|
||||||
error_messages={
|
error_messages={
|
||||||
'unique': _("A user with that username already exists."),
|
'unique': "A user with that username already exists.",
|
||||||
},)
|
},
|
||||||
|
)
|
||||||
first_name = None
|
first_name = None
|
||||||
last_name = None
|
last_name = None
|
||||||
email = models.EmailField(_('email address'))
|
email = models.EmailField('email address')
|
||||||
|
|
||||||
def get_full_name(self):
|
def get_full_name(self):
|
||||||
return None
|
return None
|
||||||
|
|
45
users/validators.py
Normal file
45
users/validators.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Some custom validators for the user model.
|
||||||
|
"""
|
||||||
|
from django.core.validators import BaseValidator
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
class MaximumLengthValidator:
|
||||||
|
"""
|
||||||
|
Validate whether the password exceeds a maximum length.
|
||||||
|
"""
|
||||||
|
def __init__(self, max_length=1024):
|
||||||
|
self.max_length = max_length
|
||||||
|
|
||||||
|
def validate(self, password, user=None):
|
||||||
|
if len(password) > self.max_length:
|
||||||
|
raise ValidationError(
|
||||||
|
"This password is too long. It must contain at most " \
|
||||||
|
+ f"{self.max_length} characters.",
|
||||||
|
code="password_too_long",
|
||||||
|
params={'max_length': self.max_length}
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_help_text(self):
|
||||||
|
msg = f"Your password must contain less than {self.max_length} " \
|
||||||
|
+ "characters."
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
class CharValidator(BaseValidator):
|
||||||
|
"""
|
||||||
|
Raises a ValidationError with a code of 'invalid_chars' if value is not
|
||||||
|
a string or contains letters which are not also within limit_value.
|
||||||
|
"""
|
||||||
|
message = 'Ensure this value only contains the characters "%(limit_value)s".'
|
||||||
|
code = 'invalid_chars'
|
||||||
|
|
||||||
|
def compare(self, value, limit_value):
|
||||||
|
assert type(limit_value) == str
|
||||||
|
if type(value) != str:
|
||||||
|
return True
|
||||||
|
for c in value:
|
||||||
|
if c not in limit_value:
|
||||||
|
return True
|
||||||
|
return False
|
Loading…
Reference in New Issue
Block a user