1

現在、Django のビルトイン管理システムを使用してユーザーを管理しています。これには、以下を使用して追加データを含むプロファイルをアタッチしました。

class Profile(models.Model):
    user = models.OneToOneField(User, editable = False)
    # Data fields here...

現状では、ユーザーが作成された直後にプロファイルが作成された場合にのみ、ユーザーとプロファイルの pk (およびそれに応じて ID 番号) は同じになります。登録プロセス中にこれが当てはまることを保証できます。これでほとんどの用途がカバーされますが、管理インターフェイスを使用してユーザーを作成すると、ID の不一致が発生する可能性があります。したがって、これはこの問題を解決するための非常に堅牢な方法とは思えず、pk を同じになるようにハードコードしたいと思います。これを行う方法がわかりません。

私は次のことがうまくいくと思いました:

profile_id = models.IntegerField(default=user.pk, editable = False, 
                                 primary_key = True)

しかし、それは私にエラーを与えます:

AttributeError: 'OneToOneField' has no attribute 'pk'

プロファイルとユーザーが同じ pk を持っていることを保証する最善の方法は何ですか? 注: OneToOneField を使用して 2 つをリンクすることで、私のすべてのニーズに十分に対応できるように思われるため、ベース ユーザー モデルの拡張には実際には対処したくありません。

ありがとう!

[編集]

質問をする私の理由:

当面の問題は、 を使用して取得していたユーザー プロファイルの値の辞書が必要だったことprofile_values = Profile.objects.filter(pk=user.id).values()[0]です。これによりバグが浮き彫りになり、昨夜、pk=user.profile.id代わりに使用して「ハッキング」しました。朝の光では、これはそれほどひどいハックのようには見えません. ただし、pk の不一致があると、静かでバグを見つけにくくなる可能性があるため、強制的に一致させることは良い考えです。しかし、私は Django を初めて使用するので、コードを正しく記述していれば、実際には問題にならないことを完全に受け入れます。とはいえ、ほとんど学術的な理由から、これどのように解決されるのか興味があります。

[/編集]

4

2 に答える 2

0

2 つのモデル間に OneToOne マッピングがあるため、問題が発生しなかったことにすでに同意しているようです。したがって、ユーザーに対応するプロファイル obj を取得する必要がある場合:

profile_values = Profile.objects.get(user_id=user)

仮定すると、

class Profile(models.Model):
    user = models.OneToOneField(User)
    ...

列名が user でない場合は、get クエリで対応する名前を使用します。

それでも、両方のモデルで同じ pk を達成する方法に興味がある場合は、User モデルを保存するたびにシグナルを設定できます。ドキュメントを参照してください。

def create_profile(sender, **kwargs):
    if kwargs["created"]:
        p = Profile(user=kwargs["instance"], ...)
        p.save()
django.db.models.signals.post_save.connect(create_profile, sender=User)

create_profile() は、User オブジェクトが保存されるたびに呼び出されます。この関数では、新しい User インスタンスが作成された場合にのみ Profile オブジェクトを作成します。

白紙の状態から始めると、すべてのユーザーにプロファイルが存在し、ユーザーが作成された直後に作成されることが常に保証されると思います。これにより、両方のモデルで同じ pk が得られます。

于 2013-06-17T12:39:13.230 に答える