Removing case sensitivity from Email in Django login form

前端 未结 3 1231
旧时难觅i
旧时难觅i 2021-01-12 14:28

Before anyone marks it as duplicate, I\'ve searched everywhere and didn\'t find. I\'ve created a custom UserModel and used Email as main authenticating id instead of usernam

相关标签:
3条回答
  • 2021-01-12 14:42

    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.

    0 讨论(0)
  • 2021-01-12 14:44

    When creating the account entry, interpret the email as email.lower() to create a normalised entry in your database.

    When parsing the email/username from a log in form, you should also use email.lower() to match the database entry.


    Note: the normalize_email only sanitises the domain portion of an email address:

    classmethod normalize_email(email)

    Normalizes email addresses by lowercasing the domain portion of the email address.

    0 讨论(0)
  • 2021-01-12 14:56

    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.

    This will just lowercase anything being saved to the UserModel.

    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...
    
    0 讨论(0)
提交回复
热议问题