web-dev-qa-db-ja.com

Django 1.5カスタムユーザーモデルでユーザー名フィールドとしてメールを使用すると、FieldErrorが発生します

カスタムユーザーモデルのユーザー名フィールドとしてメールフィールドを使用したいと思います。 DjangoのAbstractUserモデルをサブクラス化する次のカスタムユーザーモデルがあります。

class CustomUser(AbstractUser):
    ....
    email = models.EmailField(max_length=255, unique=True)

    USERNAME_FIELD = 'email'

しかし、私が走るとき

python manage.py sql myapp

次のエラーが発生します。

FieldError:クラス「CustomUser」のローカルフィールド「email」が基本クラス「AbstractUser」の同様の名前のフィールドと衝突します

そもそも自分のメールフィールドを含める理由は、それにunique=Trueオプションを追加するためです。そうでなければ私は得る:

myapp.customuser:USERNAME_FIELDは一意である必要があります。フィールドパラメータにunique = Trueを追加します。

さて、これに関して: https://docs.djangoproject.com/en/1.5/topics/db/models/#field-name-hiding-is-not-permitted
どうすればこれを達成できますか? (それ以外の場合は、フィールドに「user_email」などの名前を付けます)

22
OrPo

イアン、賢い反応をありがとう:)

しかし、私はすでに解決策を「パッチ」しています。

AbstractUserにもusernameフィールドがあるので、これは私にはまったく不要です。
「自分の」AbstractUserを作成することにしました。

AbstractBaseUserPermissionsMixinをサブクラス化することで、コードを追加せずに、ほとんどのUserモデルの組み込みメソッドを保持します。

また、この機会を利用してカスタムManagerを作成し、usernameフィールドでの使用をすべて排除しました。

from Django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager

class CustomUser(AbstractBaseUser, PermissionsMixin):
     ....
     email = models.EmailField(max_length=255, unique=True)
     first_name = ...
     last_name = ...
     is_active = ...
     is_staff = ...
     ....

     objects = CustomUserManager()

     USERNAME_FIELD = 'email'


class CustomUserManager(BaseUserManager):
     def create_user(self, email, password=None, **extra_fields):
          .....

     def create_superuser(self, email, password, **extra_fields):
          .....

このソリューションでは、Djangoの組み込みコードの一部(主に「first_name」、「last_name」などのAbstractUserにすでに存在するモデルフィールド)が繰り返されますが、よりクリーンなUserオブジェクトとデータベーステーブルも繰り返されます。 。

1.5でUSERNAME_FIELDを使用して柔軟に導入されたものを使用して実際に既存のすべての制約の下で柔軟なユーザーモデルを作成できないのは本当に残念です。

編集:公式ドキュメントで利用可能な包括的な実例があります: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#a-full-example

37
OrPo

実際のターゲットが一意の「電子メール」値であり、「ユーザー名」値を無視している場合は、次のことができます。

  • 「ユーザー名」に例を入力します。 sha256(user.email).hexdigest()[:30]
  • この方法で一意性を追加します。

    class User(AbstractUser):
        class Meta:
            unique_together = ('email', )
    

その結果、次のようになります。

CREATE TABLE "myapp_user" (
    ...
    "email" varchar(75) NOT NULL,
    UNIQUE ("email")
)

期待どおりに動作し、非常にシンプルです。

9
Denis Ryzhkov

公式サイトの例を使用してください:

https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#a-full-example

これは、管理者準拠のカスタムユーザーアプリの例です。このユーザーモデルは、ユーザー名として電子メールアドレスを使用し、必要な生年月日があります。ユーザーアカウントの単純な管理者フラグ以外に、権限チェックは提供されません。このモデルは、ユーザー作成フォームを除くすべての組み込みの認証フォームおよびビューと互換性があります。この例は、ほとんどのコンポーネントがどのように連携するかを示していますが、実稼働で使用するためにプロジェクトに直接コピーすることを意図したものではありません。

2
maxbellec