Существует ли эффективный способ предотвратить регистрацию в django одних и тех же адресов электронной почты, зарегистрированных с разной капитализацией?
В views.py
if User.objects.filter(email = email).exists():
messages.info(request, 'Email already in use')
return redirect('signup')
Django проверяет, существует ли точный email с точной капитализацией. например, если в объекте пользователя есть johndoe@yahoo.com. и я регистрируюсь с jOHNDoe@yahoo.com, вместо того, чтобы сказать ему, что email уже используется, он создает другого пользователя для gmail с его уникальной капитализацией.
Для этого вы можете использовать iexact
.
Точное совпадение без учета регистра. Если значение, предоставленное для сравнения, равно None, оно будет интерпретировано как SQL NULL.
Пример из документации:
Blog.objects.get(name__iexact='beatles blog')
Blog.objects.get(name__iexact=None)
В вашем случае:
if User.objects.filter(email__iexact=email).exists():
...
Django BaseUserManager делает нормализацию, но только доменной части. Если вы хотите нормализовать локальную часть адреса электронной почты, вам нужно нормализовать данные при создании объекта.
Возможно сделать это, создав свой собственный customUserManager, как в этом примере, там вы нормализуете локальную часть и домен в lower(), модель будет отвечать за валидацию с параметром unique=True, что-то вроде:
class MyUserManager(BaseUserManager):
def create_user(self, email, date_of_birth, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=email.lower(),
)
user.set_password(password)
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()