2011-01-31 18 views
7

私はCategoryEntryの2つのモデルを持っています。私はCategory.entry_setを使用することですが、私はCategory.blogentry_setを行うことができるようにしたいが、それは利用できませんEntryDjango ForeignKey _継承モデルのセット

class Category(models.Model): 
    title = models.CharField('title', max_length=255) 
    description = models.TextField('description', blank=True) 
    ... 

class Entry(models.Model): 
    title = models.CharField('title', max_length=255)  
    categories = models.ManyToManyField(Category) 
    ... 

class ExtEntry(Entry):  
    groups= models.CharField('title', max_length=255) 
    value= models.CharField('title', max_length=255) 
    ... 

から継承する別のモデルExtEntryがあります。これが利用できない場合、私は私の最終目標であるExtEntry関連 EDIT特定Category

1にすべてがExtEntryのクエリセットは

おかげ

答えて

3

は、私は1つの特定のカテゴリに

簡単にすべてのExtEntryrelatedを取得するために別の方法が必要になります。

ExtEntry.objects.filter(categories=my_category) 

あなたが_setを使用する方法がある場合は知っていますか継承される機能

私はそれが直接のものかどうかわかりません。ドキュメントには記載されていません。

しかし、select_relatedで同様の結果を得ることは可能です。

for e in category.entry_set.select_related('extentry'): 
    e.extentry # already loaded because of `select_related`, 
       # however might be None if there is no Extentry for current e 

ExtEntryを持つエントリのみを選択することが可能である:インクルードは除外について

for e in category.entry_set.select_related('extentry').exlude(extentry=None): 
    e.extentry # now this definitely is something, not None 

悪い事はそれがterrybly非効率的なクエリを生成していることである:

SELECT entry.*, extentry.* FROM entry 
LEFT OUTER JOIN `extentry` ON (entry.id = extentry.entry_ptr_id) 
WHERE NOT (entry.id IN (SELECT U0.id FROM entry U0 LEFT OUTER JOIN 
         extentry U1 ON (U0.id = U1.entry_ptr_id) 
         WHERE U1.entry_ptr_id IS NULL)) 

だから私の履歴書は次のようになり:結果を得るためにExtEntry.objects.filter()を使用してください。後方関係(object.something_set)は単なる利便性に過ぎず、あらゆる状況で機能しません。

+0

ありがとう!これは私の問題を解決します。継承されたモデルの_set機能を使用する方法があるかどうかを知っていますか? – neolaser

+0

外部キー関係がある場合は、model.ForeignKeyModel_setを使用して、その関係があるレコードを返すことができます – neolaser

+0

これは、ExtEntryではなく、ExtEntryモデルの余分な属性への直接アクセスを持たないExtEntry型のEntryを返します。私は本当に助けてくれてありがとう! – neolaser

2

マニュアルを参照してくださいオブジェクト持って取得する別の方法を必要とするhereこれがどのように機能するか説明してください。

基本的に親モデル項目を取得できるので、暗黙的な1対1リンケージが作成されるため、その子を取得することができます。

継承関係では、子モデルとその親のそれぞれ(自動的に作成されたOneToOneFieldを介して)間のリンクが導入されます。

だから、あなたが行うことができる必要があります:

categories = Category.objects.all() 
for c in categories: 
    entries = c.entry_set.all() 
    for e in entries: 
     extentry = e.extentry 
     print extentry.value 

私が見ることができる文書化されていませんが、私は一般的に、あなたの一対一のフィールド名が低くなることを信じています継承しているモデル名のクラス・バージョンです。

+0

返信いただきありがとうございます!非常に詳細で役立つ。私はあなたがそれに近づいているのを見ることができます、私の問題は私が全体のセットを返す必要があるということです。そして、もし私が10,000のエントリーを持っていて3つのExtEntryを持っていれば、3つのエントリーを見つけるループがたくさんある...しかし、これは間違いなく動作するだろう – neolaser

+0

確かに。私はすべてのカテゴリについて示しましたが、それが特定のカテゴリであるかどうかを覚えていて、間違いなく外側のループをダンプします。 3つのExtEntryオブジェクトと1000個のオブジェクトが必要なのではないかと思うのですが、なぜエントリが 'blank = True'であるのでしょうか? –

+0

その例は少し極端だった、私はどれくらい多く持っているのだろうか。たとえそれが10,000 v 5000(同じカテゴリのすべて)だったとしても、その余分な処理は...多分私は警官にしてその方法に行かなければならないかもしれません... – neolaser

0

EntryExtEntryは別々の表になっているため、問題が発生しています。これはあなたにとって最善の解決策かもしれませんが、マルチテーブルの継承を使用することを選択するときは注意する必要があります。

category.entry_set.exclude(extentry=None)のようなものがうまくいくはずです。

関連する問題