2011-01-31 69 views
7

我有两个模型CategoryEntry。还有,从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) 
    ... 

继承我能够使用Category.entry_set,但我希望能够做到Category.blogentry_set但它是不可用另一种模式ExtEntry。如果这是不可用的,那么我就需要另一种方法来获取所有ExtEntry与一个特定的Category

编辑 我的最终目标是有ExtEntry的一个QuerySet对象

感谢

回答

3

我需要另一种方法来获取所有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)只是一种方便,并不适用于任何情况。

2

参见文档here为解释这是如何工作的。

基本上,因为您可以获取父模型项目,所以您应该能够获取其子项,因为创建了隐式的一对一连接。

继承关系引入了子模型与其父母(通过自动创建的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 2011-01-31 23:01:55

+0

的确。我已经显示所有类别,但记住,如果它只是一个特定的类别,肯定转储外部循环。我倾向于认为如果您只需要三个ExtEntry对象与1000个对象,为什么不只是在Entry中使用`blank = True`字段? – 2011-01-31 23:09:32

0

您遇到的问题是因为EntryExtEntry位于单独的表格中。这对你来说可能是最好的解决方案,但是当你选择使用多表继承时,你应该意识到这一点。

category.entry_set.exclude(extentry=None)应该为你工作。