既存のユーザー モデルの拡張 で説明されているように、「プロファイル」モデル (ユーザー モデルと 1 対 1 の関係を持つ) を作成しました。プロファイル モデルには、別のモデルとのオプションの多対 1 の関係があります。
class Profile(models.Model):
user = models.OneToOneField(User, primary_key=True)
account = models.ForeignKey(Account, blank=True, null=True, on_delete=models.SET_NULL)
そこに記載されているように、インライン管理者も作成しました。
class ProfileInline(admin.StackedInline):
model = Profile
can_delete = False
verbose_name_plural = 'profiles'
# UserAdmin and unregister()/register() calls omitted, they are straight copies from the Django docs
ユーザーを作成するときに管理者でを選択しないaccount
と、プロファイル モデルが作成されません。したがって、ドキュメントに従って、 post_save信号に接続します。
@receiver(post_save, sender=User)
def create_profile_for_new_user(sender, created, instance, **kwargs):
if created:
profile = Profile(user=instance)
profile.save()
これは、管理者で を選択しない限り問題なく動作しますが、選択すると例外が発生し、次のように通知されます。account
IntegrityError
duplicate key value violates unique constraint "app_profile_user_id_key" DETAIL: Key (user_id)=(15) already exists.
どうやら、インライン管理者はprofile
インスタンス自体を作成しようとしますが、post_save
その時点でシグナル ハンドラーが既にインスタンスを作成しています。
次の要件をすべて維持しながら、この問題を解決するにはどうすればよいですか?
- 新しいユーザーがどのように作成さ
profile
れても、後でそれにリンクするモデルが常に存在します。 account
ユーザーの作成時にユーザーが admin でを選択すると、後でaccount
新しいprofile
モデルに設定されます。そうでない場合、フィールドはnull.
環境: Django 1.5、Python 2.7
関連する質問:
- 拡張ユーザー プロファイルの作成(同様の症状ですが、別の原因であることが判明しました)