how to create validator for lowercase user in Django 2.0?
Question:
my site is up and running. However, silly me I didnt put in a validator to check if users and username can only be in lower-case (I only realised that DJANGO allowed capitalized Users and usernames). Although, I have put up a warning but users usually ignore that still write upper case letters or alteast capitalized letters in their signup forms. I then encounter the problem of slugs not working, thereafter I have to manually change their usernames. I do not want to change the behavior of slugs and instead can I please ask for help from someone in changing my views? I have tried .lower() .format() as well and it didnt work. I am very weak on validators.
forms.py
from django.contrib.auth.models import User
from django import forms
from captcha.fields import CaptchaField
class SignUpForm(forms.ModelForm):
captcha = CaptchaField()
password = forms.CharField(max_length= 15, widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'email', 'password']
Views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth import authenticate, login
from django.views import generic
from django.views.generic import View
from home.forms import SignUpForm
class SignUpFormView(View):
form_class = SignUpForm
template_name = 'home/signup.html'
#if there is no sign up yet
def get(self,request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
#if going to sig up
def post(self,request):
form = self.form_class(request.POST)
if form.is_valid():
#it takes information but does save it
user = form.save(commit = False)
#cleaned normalized data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
#returns if it is all correct
user = authenticate(username = username, password = password)
if user is not None:
if user.is_active:
login(request, user)
return redirect("userprofile:newprofile")
return render(request, self.template_name, {'form': form})
Answers:
You can add a validation in the SignupForm
:
from django.contrib.auth.models import User
from django import forms
from captcha.fields import CaptchaField
class SignUpForm(forms.ModelForm):
captcha = CaptchaField()
password = forms.CharField(max_length= 15, widget=forms.PasswordInput)
def clean_username(self):
data = self.cleaned_data['username']
if not data.islower():
raise forms.ValidationError("Usernames should be in lowercase")
return data
class Meta:
model = User
fields = ['username', 'email', 'password']
So in case the data.islower()
check fails (the username
contains uppercase characters), it will raise a ValidationError
, and thus the form is not valid.
Note that islower()
only checks case-based characters, so if the string contains digits, it will still succeed. You thus might want to finetune the check. Or as specified in the documentation of str.islower
:
Return True
if all cased characters in the string are lowercase and
there is at least one cased character, False
otherwise.
An alternative might be to convert the data to lowercase, such that a user that enters 'FooBar'
gets as username foobar
, although this can result in the fact that users get confused that the username they picked is not the username they get.
Change username = form.cleaned_data['username']
to username = form.cleaned_data['username'].lower()
You can create a validator.
- create validators.py
from django.core.exceptions import ValidationError
def validate_lower_case(value):
if not value.islower():
raise ValidationError('You must use only lowercase letters!')
- your models
from django.db import models
from .validators import validate_lower_case
class User(models.Model):
first_name = models.CharField(validators=[validate_lower_case])
my site is up and running. However, silly me I didnt put in a validator to check if users and username can only be in lower-case (I only realised that DJANGO allowed capitalized Users and usernames). Although, I have put up a warning but users usually ignore that still write upper case letters or alteast capitalized letters in their signup forms. I then encounter the problem of slugs not working, thereafter I have to manually change their usernames. I do not want to change the behavior of slugs and instead can I please ask for help from someone in changing my views? I have tried .lower() .format() as well and it didnt work. I am very weak on validators.
forms.py
from django.contrib.auth.models import User
from django import forms
from captcha.fields import CaptchaField
class SignUpForm(forms.ModelForm):
captcha = CaptchaField()
password = forms.CharField(max_length= 15, widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'email', 'password']
Views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth import authenticate, login
from django.views import generic
from django.views.generic import View
from home.forms import SignUpForm
class SignUpFormView(View):
form_class = SignUpForm
template_name = 'home/signup.html'
#if there is no sign up yet
def get(self,request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
#if going to sig up
def post(self,request):
form = self.form_class(request.POST)
if form.is_valid():
#it takes information but does save it
user = form.save(commit = False)
#cleaned normalized data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
#returns if it is all correct
user = authenticate(username = username, password = password)
if user is not None:
if user.is_active:
login(request, user)
return redirect("userprofile:newprofile")
return render(request, self.template_name, {'form': form})
You can add a validation in the SignupForm
:
from django.contrib.auth.models import User
from django import forms
from captcha.fields import CaptchaField
class SignUpForm(forms.ModelForm):
captcha = CaptchaField()
password = forms.CharField(max_length= 15, widget=forms.PasswordInput)
def clean_username(self):
data = self.cleaned_data['username']
if not data.islower():
raise forms.ValidationError("Usernames should be in lowercase")
return data
class Meta:
model = User
fields = ['username', 'email', 'password']
So in case the data.islower()
check fails (the username
contains uppercase characters), it will raise a ValidationError
, and thus the form is not valid.
Note that islower()
only checks case-based characters, so if the string contains digits, it will still succeed. You thus might want to finetune the check. Or as specified in the documentation of str.islower
:
Return
True
if all cased characters in the string are lowercase and
there is at least one cased character,False
otherwise.
An alternative might be to convert the data to lowercase, such that a user that enters 'FooBar'
gets as username foobar
, although this can result in the fact that users get confused that the username they picked is not the username they get.
Change username = form.cleaned_data['username']
to username = form.cleaned_data['username'].lower()
You can create a validator.
- create validators.py
from django.core.exceptions import ValidationError
def validate_lower_case(value):
if not value.islower():
raise ValidationError('You must use only lowercase letters!')
- your models
from django.db import models
from .validators import validate_lower_case
class User(models.Model):
first_name = models.CharField(validators=[validate_lower_case])