2012-03-30 23 views
16

Djangoのmodels.ForeignKey(Modelname, unique=True)models.OneToOneFieldの違いは何ですか?ForeignKey(User、unique = True)とOneToOneFieldの違い

ここではmodels.OneToOneFieldmodels.ForeignKey(Modelname, unique=True)を使用しますか?

+0

@alanこのAlasdirの回答では、Alasdirの回答がコンセプトを非常によく説明しているとは限りません。 – Hafiz

答えて

38

OneToOneFieldは、ForeignKeyと非常によく似ています。unique=Trueです。複数のテーブル継承を行っている場合を除いて、OneToOneFieldを使用する必要がある場合を除き、唯一の違いは関連するオブジェクトにアクセスするためのAPIです。 Django docs

それは言う:

概念的には、これはunique=TrueForeignKeyに似ていますが、関係の「逆」側が直接、単一のオブジェクトを返します。

例で意味することを見てみましょう。 PersonAddressの2つのモデルを考えてみましょう。それぞれの人に固有のアドレスがあると仮定します。

class Person(models.Model): 
    name = models.CharField(max_length=50) 
    address = models.ForeignKey('Address', unique=True) 

class Address(models.Model): 
    street = models.CharField(max_length=50) 

あなたは一人で始めた場合、あなたは簡単にアドレスをアクセスすることができます:あなたはアドレスで始まる場合

address = person.address 

はしかし、あなたは人を取得するためにperson_setマネージャを経由して行かなければなりません。

person = address.person_set.get() # may raise Person.DoesNotExist 

今度はOneToOneFieldForeignKeyを交換しましょう。あなたは一人で始めた場合

class Person(models.Model): 
    name = models.CharField(max_length=50) 
    address = models.OneToOneField('Address') 

class Address(models.Model): 
    street = models.CharField(max_length=50) 

、あなたは同じようにアドレスにアクセスすることができます。

address = person.address 

そして今、我々はより簡単にアドレスから人にアクセスすることができます。

person = address.person # may raise Person.DoesNotExist 
+1

Personクラスの "address = models.ForeignKey(Address、unique = True)"を意味すると思います。 – alan

+0

@alan - 良いキャッチ、今すぐ修正。 – Alasdair

1

、あなたが照会フィールドの値を取得OneToOneFieldにアクセスします。この例では、本モデルの「タイトル」フィールドがOneToOneField次のとおりです。

>>> from mysite.books.models import Book 
>>> b = Book.objects.get(id=50) 
>>> b.title 
u'The Django Book' 

あなたは、あなたが、その後に対してさらにクエリをプリフォームすることができ、関連するモデルオブジェクトを取得ForeignKeyにアクセスすると。この例では、同じ本モデルの「発行者」フィールドは、ForeignKeyは(Publisherクラスモデルの定義に相関する)である:

>>> b = Book.objects.get(id=50) 
>>> b.publisher 
<Publisher: Apress Publishing> 
>>> b.publisher.website 
u'http://www.apress.com/' 

ForeignKeyフィールドクエリがあまりにも他の方法で動作しますが、それらが原因と若干違っていると関係の非対称的な性質。舞台裏

>>> p = Publisher.objects.get(name='Apress Publishing') 
>>> p.book_set.all() 
[<Book: The Django Book>, <Book: Dive Into Python>, ...] 

、book_setはちょうどQuerySetで、濾過して、他のQuerySetのようにスライスすることができます。属性名book_setは、小文字のモデル名を_setに追加することによって生成されます。 これは、作成された関係の違いを説明するのに役立ちます。

関連する問題