目前,在django.contrib.auth中,可以有两个用户名为“john”和“John”的用户。我该如何防止这种情况发生。
最简单的方法是在contib.auth.models中添加一个干净的方法,并在保存之前将其转换为小写,但我不想编辑contrib.auth包。
感谢。
答案 0 :(得分:4)
在pre_save
上收听Users
模型,然后在那里进行检查。最少侵入性和最便携的方式。
以下是一个关于它的外观的示例(改编自用户配置文件示例):
def username_check(sender, instance, **kwargs):
if User.objects.filter(username=instance.username.lower()).count():
raise ValidationError('Duplicate username')
pre_save.connect(username_check, sender=User)
答案 1 :(得分:0)
如果您使用Postgres,还有更好的选择。 Postgres具有不区分大小写的字段类型citext
。从1.11开始,Django在django.contrib.postgres.fields.citext
中提供了此功能。您可能还需要在url正则表达式中处理区分大小写。
答案 2 :(得分:0)
我可能会使用用户名的自定义字段在模型上解决此问题。
from django.db import models
class LowercaseCharField(models.CharField):
"""
Override CharField to convert to lowercase before saving.
"""
def to_python(self, value):
"""
Convert text to lowercase.
"""
value = super(LowercaseCharField, 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
然后在您的模型中。
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.utils.translation import gettext_lazy as _
# Assuming you saved the above in the same directory in a file called model_fields.py
from .model_fields import LowercaseCharField
class User(AbstractUser):
username = LowercaseCharField(
# Copying this from AbstractUser code
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[UnicodeUsernameValidator(),],
error_messages={
'unique': _("A user with that username already exists."),
},
)
# other stuff...
所有用户名都将“自动”保存为小写。