24

カスタムユーザーモデルのユーザー名フィールドとしてメールフィールドを使用したいと思います。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」などの名前を付けます)

4

4 に答える 4

36

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

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

私にとって全く不要なフィールド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):
          .....

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

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

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

于 2013-03-25T00:30:56.997 に答える
10

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

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

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

これにより、次のようになります。

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

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

于 2013-07-03T17:40:49.237 に答える
9

を編集して、フィールド属性をCustomUserに変更できます。emailunique=True

次のように、カスタムユーザークラスの最後にこれを追加します。

class CustomUser(AbstractUser):
    ...
    USERNAME_FIELD = 'email'
    ...
CustomUser._meta.get_field_by_name('email')[0]._unique=True

後者が単純であるためでは_uniqueなく、変更していることに注意してください。unique@property

これはハックです。これを解決するための「公式」の回答をお待ちしています。

于 2013-03-24T20:50:49.717 に答える
2

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

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

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

于 2014-10-24T23:48:44.107 に答える