29

Djangoユーザーモデルを拡張してモデルを使用するかどうか、OneToOneField(User)またはForeignKey(User, unique=True)作成するときに矛盾する情報を見つけました。UserProfile

これを使用する方が良いですか?:

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)

またはこれ?:

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

Django Docはを指定OneToOneFieldしますが、 DjangoBookのはを使用しForeignKeyます。

James Bennettには、矛盾する例を提供する2つのブログ投稿もあります。

ForeignKey前の投稿で、ベネットは彼が代わりに使用するように切り替えたいくつかの理由を提供してOneToOneFieldいますが、特に反対を推奨する他の投稿を見ると、私はそれを完全には理解していません。

私はあなたの好みとその理由を知りたいです。または、それも重要ですか?

4

3 に答える 3

19

Userこの記事で説明されている唯一の本当の理由は、 の管理ページにと の両方のフィールドが表示されるように設定できるUserからUserProfileです。OneToOneFieldこれは、ちょっと手間をかければ再現できるので、管理ページに表示するのに慣れていない限り、わかりやすさが犠牲になります (「ユーザーごとに複数のプロファイルを作成できますか?! ああ、いや、待ってください、それは一意に設定されています。") 私はOneToOneField.

于 2010-07-11T05:08:21.923 に答える
7

管理ページのインラインに加えて、ソリューションの他の理由は、ForeignKeyオブジェクトが逆の関係でアクセスされるときに、正しいデフォルトの DB マネージャーを使用できるようにすることです。このsubclasses manager snippet の例を考えてみましょう。例のPostクラス定義が次のようになっているとします。

class Post(ParentModel):
    title = models.CharField(max_length=50)
    onetoone = models.ForeignKey(SomeModel, unique=True)

    children = ChildManager()
    objects = models.Manager()

を呼び出すと、最初の (デフォルト) マネージャを として定義することで示されるようsomemodel_instance.post_set.all()[0]に、クラスの目的のサブクラス オブジェクトを取得できます。一方、 を呼び出すと、クラスのインスタンスが取得されます。いつでも呼び出して同じ結果を得ることができますが、デフォルトのマネージャーは他の種類のトリックを行うことができ、ソリューションはそれらをうまく隠します。PostChildManagerOneToOneFieldsomemodel_instance.postPostsomemodel_instance.post.subclass_objectFK

カスタム マネージャー コードを所有していて変更できる場合はuse_for_related_fields、正当な 1to1 フィールドの代わりに FK を使用する代わりに属性を使用できますが、自動マネージャーの未知の迷惑のために失敗する可能性があります。私が覚えている限り、上記の例では失敗します。

于 2010-08-09T17:02:28.627 に答える
5

逆関係に関連するものを一般的に使用しないその他の理由OneToOneField:逆関係とは対照的に、を介して定義された逆関係を使用すると、OneToOneFieldモデルインスタンスが取得され、その結果、常にDBヒットが発生します。これは、(を介して)逆の関係でいくつかの一般的なことを行い、それらすべてを使用するかどうかを知らず、気にしない場合、コストがかかります。ManagerForeignKey_meta.get_all_related_objects()

于 2010-11-17T15:15:56.423 に答える