I've created a custom UserModel and used Email as main authenticating id instead of username.
The problem that it is case sensitive, as it counts [email protected],[email protected] as 2 different accounts.
I need to force it to deal with both as 1 account ignoring if it upper or lower case.
Here are my files :
models.py
class UserModelManager(BaseUserManager):
def create_user(self, email, password, pseudo):
user = self.model()
user.name = name
user.email = self.normalize_email(email=email)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password):
'''
Used for: python manage.py createsuperuser
'''
user = self.model()
user.name = 'admin-yeah'
user.email = self.normalize_email(email=email)
user.set_password(password)
user.is_staff = True
user.is_superuser = True
user.save()
return user
class UserModel(AbstractBaseUser, PermissionsMixin):
## Personnal fields.
email = models.EmailField(max_length=254, unique=True)
name = models.CharField(max_length=16)
## [...]
## Django manage fields.
date_joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELD = ['email', 'name']
objects = UserModelManager()
def __str__(self):
return self.email
def get_short_name(self):
return self.name[:2].upper()
def get_full_name(self):
return self.name
signup view in views.py
def signup(request):
if request.method == 'POST':
signup_form = SignUpForm(request.POST)
if signup_form.is_valid():
signup_form.save()
username = signup_form.cleaned_data.get('username')
raw_password = signup_form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
return redirect('signup_confirm')
else:
signup_form = SignUpForm()
context = {
'signup_form': signup_form,
}
return render(request, 'fostania_web_app/signup.html', context)
def signup_confirm(request):
return render(request, 'fostania_web_app/signup_confirm.html')
the sign up form in forms.py:
class SignUpForm(UserCreationForm):
email = forms.CharField(required=True, help_text='البريد الإلكترونى الخاص بك - يجب ان يكون حقيقى (يستخدم لتسجيل الدخول) ')
name = forms.CharField(required=True, help_text='إسمك الحقيقى - سيظهر كأسم البائع')
password1 = forms.CharField(widget=forms.PasswordInput,
help_text='كلمة المرور - حاول ان تكون سهلة التذكر بالنسبة لك')
password2 = forms.CharField(widget=forms.PasswordInput,
help_text='تأكيد كلمة المرور - إكتب نفس كلمة المرور السابقة مرة أخرى')
class Meta:
model = UserModel
fields = ('email','name', 'password1', 'password2', )
labels = {
'name': 'إسمك الحقيقى - سيظهر كأسم البائع',
'email': 'البربد الإلكترونى Email',
'password1': 'كلمة المرور',
'password2': 'تأكيد كلمة المرور'
}
All that I need now is to make it simply ignores the case sensitivity.
update
here is my login files
urls.py
path('login/', auth_views.login, name='login'),
registartion/login.html
<form method="post">
{% csrf_token %}
البريد الإلكترونى E-Mail <Br>{{ form.username }}
<br><br>
كلمة المرور <Br>{{ form.password }}
<Br><br>
<div align="center">
<button class ="btn btn-primary" submit>تسجيل الدخول</button><br><br>
<a href="{% url 'signup' %}"><button type="button" class="btn btn-warning">
إنشاء حساب جديد</button></a>
</div>
</form>
Show activity on this post. Django by-default implements username as case sensitive, now for authentication I have written my own Authentication Backend to handle case insensitive usernames while authentication. Now, the problem is : I have various views and util methods which compares username to some stings.
You have to declare the email field in your AbstractBaseUser model as unique=True .
Approach No 1: Python String lower() Method This is the most popular approach to case-insensitive string comparisons in Python. The lower() method converts all the characters in a string to the lowercase, making it easier to compare two strings.
A cleaner approach might be to override the model field itself if you don't mind losing the formatting of how the user entered their email.
This worked better for me because I only had to change it in one place. Otherwise, you might have to worry about Signup, Login, User Update, API views, etc.
The only method you will have to overwrite is to_python. This will just lowercase anything being saved to the UserModel.email field.
from django.db import models
class LowercaseEmailField(models.EmailField):
"""
Override EmailField to convert emails to lowercase before saving.
"""
def to_python(self, value):
"""
Convert email to lowercase.
"""
value = super(LowercaseEmailField, self).to_python(value)
# Value can be None so check that it's a string before lowercasing.
if isinstance(value, str):
return value.lower()
return value
Your user model would then just be..
# Assuming you saved the above in the same directory in a file called model_fields.py
from .model_fields import LowercaseEmailField
class UserModel(AbstractBaseUser, PermissionsMixin):
email = LowercaseEmailField(unique=True)
# other stuff...
You don't need to change much to accomplish this - in your case you just need to change the form and make use of Django's built-in form data cleaners or by making a custom field.
You should use the EmailField instead of a CharField for built-in validation. Also you did not post your AuthenticationForm, but i presume you have changed it to include email instead of username.
With data cleaners:
class SignUpForm(UserCreationForm):
# your code
email = forms.EmailField(required=True)
def clean_email(self):
data = self.cleaned_data['email']
return data.lower()
class AuthenticationForm(forms.Form):
# your code
email = forms.EmailField(required=True)
def clean_email(self):
data = self.cleaned_data['email']
return data.lower()
With a custom field:
class EmailLowerField(forms.EmailField):
def to_python(self, value):
return value.lower()
class SignUpForm(UserCreationForm):
# your code
email = EmailLowerField(required=True)
class AuthenticationForm(forms.Form):
# your code
email = EmailLowerField(required=True)
This way you can make sure that each email is saved to your database in lowercase and that for each login attempt the email is lowercased before compared to a database value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With