在Django中强制使用小写的用户名

时间:2012-08-12 13:49:42

标签: django

目前,在django.contrib.auth中,可以有两个用户名为“john”和“John”的用户。我该如何防止这种情况发生。

最简单的方法是在contib.auth.models中添加一个干净的方法,并在保存之前将其转换为小写,但我不想编辑contrib.auth包。

感谢。

3 个答案:

答案 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...

所有用户名都将“自动”保存为小写。