鉴于以下模型:(不要介意TextFields只是为了说明)
class Base(models.Model):
field1 = models.TextField()
class Meta:
abstract=True
class Child1(Base):
child1_field = models.TextField()
class Child2(Base):
child2_field = models.TextField()
class Content(models.Model):
aso_items = models.ManyToManyField('Base')
根据这些定义,Content对象可以与多个Base对象相关联,例如。面试(=内容对象)可以与音乐家(= Child1对象),电影导演(= Child2)等链接。
现在,对于我的问题: 是否可以根据aso_items字段指向的模型过滤Content对象? 例如:假设我想要一个Queryset,其中包含与Child1的特定对象相关联的所有Content对象(例如,与音乐家Bob Dylan相关的所有访谈),我该如何实现?
此外,如果我想要一个包含与Child1对象关联的所有Content对象的QuerySet,那该怎么办?(例如,所有与音乐家相关的访谈) 这如何改变过滤?
提前致谢 ps:我在预览中遇到了一些空白问题,请原谅我
答案 0 :(得分:7)
您应该检查Django文档中有关使用related_name
进行抽象基类的部分。 http://docs.djangoproject.com/en/dev/topics/db/models/#be-careful-with-related-name
引用文档:
如果您使用
related_name
ForeignKey或的属性 ManyToManyField,你必须永远 为。指定唯一的反向名称 领域。这通常会导致 抽象基类中的问题, 因为这个类的字段是 包括在每个孩子中 类,具有完全相同的值 对于属性(包括 每次related_name
)。解决这个问题,当你 在摘要中使用related_name 基类(仅),名称的一部分 应该是字符串
%(class)s
。这个 被替换为低级的名称 使用该字段的子类 因为每个班级都有不同 名称,每个相关名称将最终 与众不同。
使用此信息,我建议将m2m字段移动到Base类:
class Content(models.Model):
# Add remaining fields for Content
pass
class Base(models.Model):
field1 = models.TextField()
items = models.ManyToManyField(Content,related_name="%(class)s_related")
class Meta:
abstract=True
class Child1(Base):
child1_field = models.TextField()
class Child2(Base):
child2_field = models.TextField()
答案 1 :(得分:2)
显然不允许使用带抽象类的ForeignKey关系(或者说很多事情)。 我收到以下错误:'AssertionError:ForeignKey无法定义与抽象类Artiest'的关系。
一种可能的解决方案是将基类定义为非抽象类,但这意味着可以实例化基类的模型。这不是我想要的行为。(毕竟它是一个抽象类) 有人遇到同样的问题你是如何解决的?任何替代方案?
答案 2 :(得分:1)
查看通过通用关系的http://www.djangoproject.com/documentation/models/generic_relations/。您的内容模型将匹配其TaggedItem模型,您的Base模型将匹配其动物/蔬菜/矿物模型(Child1和Child2扩展)。
获取单个子项的所有Content对象(假设您将GenericRelation设置为Base中的内容):
child_contents = childObject.contents.all()
获取模型的所有Content对象:
ctype = ContentType.objects.get_for_model(Child1)
all_child_contents = Content.objects.filter(content_type=ctype)