3

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

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

谢谢。

4

4 回答 4

4

聆听模型,然后在那里进行检查pre_saveUsers最少侵入性和最便携的方式。

这是一个关于它的外观示例(改编自用户配置文件示例):

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)
于 2012-08-12T13:55:36.197 回答
1

如果您使用 Postgres,则有更好的选择。Postgres 有一个不区分大小写的字段类型,citext. 从 1.11 开始,Django 在django.contrib.postgres.fields.citext. 您可能还需要处理 url 正则表达式中的大小写敏感问题。

于 2018-02-23T17:31:37.953 回答
0

将接受的答案更新为最新:

from django.db.models.signals import pre_save
from django.db.utils import IntegrityError
from django.dispatch import receiver

@receiver(pre_save, sender=User)
def username_check(instance, sender, **kwargs):
    """Ensure that username unique constraint is case insensitive"""
    if sender.objects.filter(username__iexact=instance.username.lower()):
        raise IntegrityError("Duplicate username")
于 2021-08-25T04:26:47.220 回答
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...

用户名将全部“自动”保存为小写字母。

于 2019-10-22T00:48:06.490 回答