Django / Postgres (Heroku) - Сделать имя пользователя и email нечувствительными к регистру : плюсы и минусы обращения к ним через RegisterForm

Контекст: Делаю тест с django, и мне удалось зарегистрироваться: User1 и user1.

Проблема: При запросе на получение пароля django возвращал 500 error из-за MultipleObjectsReturned exception.

Я удивлен, что Django разрешил имя пользователя с одинаковым написанием, но запутался из-за чувствительности к регистру, которую он допустил в процессе регистрации.

Полагаю, я могу либо исправить это в представлении запроса нового пароля, либо сделать аутентификацию уникальной и не зависящей от регистра.

Некоторые исследования: Кажется, лучший вариант - просто избегать дублирования имен пользователей или адресов электронной почты: если user1 зарегистрирован User1, он не может создать новую учетную запись.

Я нашел этот пост на stack: https://stackoverflow.com/questions/13190758/django-case-insensitive-matching-of-username-from-auth-user#:~:text=Самый%20простой%20путь%20к%20использованию,ModelBackend%20и%20override%20authenticate%20method.&text=Использование%20UserManager%20является%20одним%20из,без%20вмешательства%20в%20другие%20вещи

Но это довольно старое решение, и оно ссылается на мертвую ссылку. Мне интересно, произошло ли что-то в мире Django, чтобы решить эту проблему?

Мое решение: Поскольку я не до конца уверен в своей способности переопределить ModelBackend, я пришел к следующему решению, изменив RegisterForm:

class  RegisterForm(UserCreationForm):
    email = forms.EmailField(required=True)
    age_group = forms.ChoiceField(choices=AGE_GROUP, required=True, widget=forms.Select(attrs={'class':'form-select','placeholder':'Tell us'}))
    
    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email__iexact=email).exists():
            raise forms.ValidationError(_("the given email is already registered"))
        return email
    
    def clean_username(self):
        username = self.cleaned_data['username']
        if User.objects.filter(username__iexact=username).exists():
            raise forms.ValidationError(_("This username is already taken. Please choose another one."))
        return username

    class Meta:
        model = User
        fields = ["username", "email", "password1", "password2","age_group"]

    def __init__(self,*args,**kwargs):
        super(RegisterForm, self).__init__(*args, **kwargs)

        #iterate over form fields and set label to false
        for field_name, field in self.fields.items():
            field.label = False

Это решение кажется намного проще, чем другие, которые я нашел. Однако я осознаю, что могу не увидеть общую картину.

Вопрос: Какие недостатки будет иметь или может вызвать это решение? Могу ли я безопасно реализовать его? Или мне следует рассмотреть возможность использования переопределения ModelBackend

Вернуться на верх