3

現在、django.contrib.authには、ユーザー名「john」と「John」の2人のユーザーがいる可能性があります。どうすればこれを防ぐことができますか。

最も簡単なアプローチは、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 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 に答える
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 に答える