19
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Djangoで認証用カスタムユーザモデルは途中で変更できません?

Last updated at Posted at 2018-02-18

djangoで認証のためのユーザモデルをプロジェクト途中でいじるときに引っかかってしまったところです.もし簡単な方法を知ってる方がいたらお教えください.

  • Django 2.0
  • python 3.6

#プロジェクト途中での認証ユーザモデルの変更

Djangoにおいて,途中でAUTH_USER_MODELの属性を変更するのはとても難しいと言うことがわかりましたので報告します.

#Djangoのデフォルトユーザモデル

djangoのデフォルトのユーザモデルは下のようになっています.
https://github.com/django/django/blob/master/django/contrib/auth/models.py

models.py
#~~~~省略
class AbstractUser(AbstractBaseUser,PermissionsMixin):
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[username_validator],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=150, blank=True)
    email = models.EmailField(_('email address'), blank=True)
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
#~~~省略

最初のmigration(init_0001)をして色々書いてからユーザモデルをいじることを始めました.必要でないfirst_namelast_nameを取りはずし再migrateしたのですが,既存のユーザモデルとかぶるからと言う理由でエラーを吐かれます.色々試したもののうまく行かず,行き着いた公式ドキュメントには以下のように書かれていました.
https://docs.djangoproject.com/ja/2.0/topics/auth/customizing/

###Changing to a custom user model mid-project¶

Changing AUTH_USER_MODEL after you've created database tables is significantly more difficult since it affects foreign keys and many-to-many relationships, for example.

This change can't be done automatically and requires manually fixing your schema, moving your data from the old user table, and possibly manually reapplying some migrations. See #25313 for an outline of the steps.

Due to limitations of Django's dynamic dependency feature for swappable models, the model referenced by AUTH_USER_MODEL must be created in the first migration of its app (usually called 0001_initial); otherwise, you'll have dependency issues.

In addition, you may run into a CircularDependencyError when running your migrations as Django won't be able to automatically break the dependency loop due to the dynamic dependency. If you see this error, you should break the loop by moving the models depended on by your user model into a second migration. (You can try making two normal models that have a ForeignKey to each other and seeing how makemigrations resolves that circular dependency if you want to see how it's usually done.)

初期migrateでデフォルトユーザモデルと他のテーブル間の参照ががっちりできるため,変更には手動で格納データを移したりしなければならないようです.しかし手動でテーブルをいじると以前のmigrateとの整合性が取れなくなり今後の変更を全部手動でやることに...(いいやり方を知らない)
ちなみにその大変だと言う解決法は以下のようです.
https://code.djangoproject.com/ticket/25313

カスタムユーザモデルの定義は絶対にしよう!

最終的な結論は以下に書かれていました.

###Using a custom user model when starting a project¶

If you're starting a new project, it's highly recommended to set up a custom user model, even if the default User model is sufficient for you. This model behaves identically to the default user model, but you'll be able to customize it in the future if the need arises:

デフォルトユーザモデルをいじるつもりでもいじるつもりじゃなくても,絶対最初からカスタムユーザモデル定義しといたほうがいいよ!

djangoでプロジェクトを作る際は,たとえフィールドが空でもユーザモデルを定義すべきのようです.

カスタムユーザモデルの定義については以下にとても詳しく書かれています.本当にありがたいです.

最終的に,途中まで書いていたプロジェクトは最初から作り直し始めました.

#結論

  • Djangoではどんなプロジェクトでもカスタムユーザモデルを定義しておくべき
  • ちゃんとドキュメントは作る前に読む
19
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?