2012-04-20 6 views
3

映画、書籍、ソフトウェアのデータベースがあり、すべてが単一のItemモデルを継承しているとします。1対1の関係が異なる可能性がある逆の一対一の関係で、どのようにprefetch_relatedできますか?

class Item(models.Model): 
    ... 

class Movie(models.Model): 
    item = models.OneToOneField(Item) 
    ... 

class Book(models.Model): 
    item = models.OneToOneField(Item) 
    ... 

class Software(models.Model): 
    item = models.OneToOneField(Item) 
    ... 

は、今私は、項目のデータベースクエリを作成したいが、私はそれは映画、書籍、またはソフトウェアかどうか、その項目に関連するオブジェクトをピックアップします。すべてのアイテムが1種類だった場合は、たとえば、映画は、私は次のことを行うことができます:

Item.objects.prefetch_related('movie') 

は、しかし、私は関係なく、それがどのようなタイプの関連オブジェクトを取得しないことができるようにする必要があります。私は実行することができます:

Item.objects.prefetch_related('movie', 'book', 'software') 

これは、どのようなタイプであっても関連するオブジェクトを見つけることができますか効率的ですか?これを行うより良い方法はありますか?

答えて

1

私はあなたのクエリセットの例は、それぞれ、つまり、'movie''book''software'を示すようOneToOneField sがrelated_nameセットがあるとします。

prefetch_relatedが1対1の関係を逆にたどるには、LEFT OUTER JOINが自動的に生成されるselect_relatedで実現するのは簡単です。ことは、あなたが

Item.objects.select_related('movie', 'book', 'software') 

を行うことができるはずと(もちろん、もしあれば)各返されたアイテムのインスタンスが自動的に対応するMovieBookSoftwareのキャッシュされたインスタンスが含まれています。あなたは多対多または多対1の関係でO(N)クエリの問題を避けたいとき

prefetch_relatedのみが必要とされ、それがManyToManyFieldまたはForeignKeyの逆方向移動と、です。