我有两个模型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
,但它不可用。如果这不可用,那么我需要另一种方法来获取与一个特定ExtEntry
相关的所有Category
EDIT 我的最终目标是拥有一个ExtEntry对象的QuerySet
由于
答案 0 :(得分:4)
我需要另一种方法将所有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)只是一种方便,并不适用于所有情况。
答案 1 :(得分: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
我没有记录,但我相信通常,您的一对一字段名称将是继承模型名称的低级版本。
答案 2 :(得分:0)
您遇到的问题是因为Entry
和ExtEntry
位于不同的表格中。这可能是最适合您的解决方案,但是当您选择使用多表继承时,您应该注意这一点。
像category.entry_set.exclude(extentry=None)
这样的东西对你有用。