10

と呼ばれるカスタムユーザープロファイルを使用して、Djangoのユーザーモデルを拡張しましたUserExtension。これは、独自の外部キー関係を介してユーザーに関連付けられているため、管理者でインライン形式で編集できます。シグナルを使用して、すべての新しいユーザーの新しいプロファイルを作成しています。

def create_user_profile(sender, instance, created, **kwargs):  
    if created:
        try:  
            profile, created = UserExtension.objects.get_or_create(user=instance)
        except:
            pass  

post_save.connect(create_user_profile, sender=User) 

(ここで説明するように、たとえば:Djangoのカスタムフィールドを使用したユーザーモデルの拡張)問題は、管理者を介して新しいユーザーを作成すると、「列user_idは一意ではありません」の保存時にIntegritiyErrorが発生することです。シグナルが2回呼び出されているようには見えませんが、管理者がプロファイルを後で保存しようとしていると思いますか?ただし、システムの他の部分で新しいユーザーを作成する場合は、シグナルによる作成が必要です。

4

1 に答える 1

15

保存は常に次のようなもので構成されるため、djangoが後でadminインスタンスを作成するのは通常のことです。

  1. ユーザーオブジェクトの作成
  2. プロファイルオブジェクトを作成します(ユーザーを指しているため、前に作成することはできません)。

Userオブジェクトを保存するとき、django ORMは、create profileオブジェクトがその後に来ることを認識できないため、post_saveシグナルを遅延させることはありません(意味がありません)。

post_saveシグナルを保持したい場合、これ(imho)を処理する最良の方法は、のsaveメソッドを次のUserExtensionようにオーバーライドすることです。

def save(self, *args, **kwargs):
    try:
        existing = UserExtension.objects.get(user=self.user)
        self.id = existing.id #force update instead of insert
    except UserExtension.DoesNotExist:
        pass 
    models.Model.save(self, *args, **kwargs)

これにより、既存のオブジェクトと同じユーザーを指すすべての挿入が強制的に更新されることに注意してください。これは、コードの他の部分では予期しない動作になる可能性があります。

于 2010-05-11T19:13:08.190 に答える