Django 继承模型中的 ForeignKey _set
我有两个模型,分别是 Category
(分类)和 Entry
(条目)。还有一个模型 ExtEntry
(扩展条目),它是从 Entry
继承过来的。
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
来获取扩展条目,但这个方法不可用。如果这个方法不可用,那我需要找其他办法来获取与特定 Category
相关的所有 ExtEntry
。
编辑:我的最终目标是得到一组 ExtEntry
对象。
谢谢!
3 个回答
你遇到的问题是因为 Entry
和 ExtEntry
在不同的表里。这种做法可能对你来说是最好的选择,但在你决定使用多表继承的时候,得注意这一点。
像 category.entry_set.exclude(extentry=None)
这样的写法应该能解决你的问题。
你可以在这里查看文档,了解这个是怎么运作的:这里。
简单来说,因为你可以获取父模型的项目,所以你应该也能获取到它的子模型,因为它们之间有一种隐含的一对一关系。
这种继承关系在子模型和每个父模型之间建立了链接(通过一个自动创建的OneToOneField)。
所以,你应该可以这样做:
categories = Category.objects.all()
for c in categories:
entries = c.entry_set.all()
for e in entries:
extentry = e.extentry
print extentry.value
虽然我没有看到相关的文档,但我相信一般来说,你的一对一字段名称会是继承模型名称的小写版本。
我需要另一种方法来获取与某个特定类别相关的所有 ExtEntry。
简单:
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
排除的坏处是,它会生成非常低效的查询:
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)只是一个方便的功能,并不是在所有情况下都能用。