【问题标题】:Django access to subclasses items from abstract classDjango从抽象类访问子类项目
【发布时间】:2013-09-11 13:40:24
【问题描述】:
class Animal(models.Model):
    ....
    class Meta:
        abstract = True

class Cat(models.Model, Animal):
    ...

class Dog(models.Model, Animal):
    ....

我希望能够返回 Animal 的所有子类的查询集的所有实例。假设我有一个名为 allData 的函数,它返回所有子类查询集的数组/列表。

例如:

x = animal.allData()[0] # should return the first element in the array.

我不介意我们如何做到这一点,是否使用 django-model-utils 之类的模块。我只是希望能够返回所有子类查询集。

【问题讨论】:

  • 请注意,这里的答案似乎都没有解决这是一个抽象基础模型的事实。答案假设一个具体的基础模型。

标签: python django


【解决方案1】:

这在一个查询中是不可能的。你有两种选择,一种使用django-model-utils,或者你可以使用django_polymorphic

Polymorphic 更适合您的任务,但是 django-model-utils 是由 django 社区的一位非常杰出的成员制作的,因此得到了很多良好的支持。

如果我必须选择,我会选择django-model-utils,因为它是由 django 团队的成员制作的,因此会得到支持。多态由 divio 提供支持,这是一家在瑞士大量使用 django 的私人公司。

关于如何选择子类。您需要使用django-model-utils 做两件事。首先,您需要将模型中的objects 变量更改为InheritanceManager(),如下所示(改编自文档):

from model_utils.managers import InheritanceManager

class Place(models.Model):
    # ...
    objects = InheritanceManager()

class Restaurant(Place):
    # ...

class Bar(Place):
    # ...

nearby_places = Place.objects.filter(location='here').select_subclasses()
for place in nearby_places:
    # "place" will automatically be an instance of Place, Restaurant, or Bar

上面的代码将返回所有Bars 和Restaurants,因为它使用了select_subclasses

【讨论】:

  • 它真的适用于抽象模型吗?我尝试在我的项目中实现它,这条线 queryset = MyAbstractModel.objects.select_subclasses() 导致错误 AttributeError: Manager isn't available; MyAbstractModel is abstract 你知道为什么它对我不起作用吗?
  • 我认为 django-model-utils 不适用于抽象基础模型。我认为这个答案对 MTI(多表继承)有效,不适用于抽象基础模型/继承
  • 按子字段过滤呢?例如,如果只有 Bar 将具有“布尔烧烤”字段并且我需要按该字段过滤所有位置?像 Places.objects.select_subclasses().filter(grill__isnull=False) 吗?我收到错误“django.core.exceptions.FieldError:无法将关键字“grill”解析到字段中。”选择是:(...进一步列出所有父字段)---->顺便说一句,这里有适当的问题--->stackoverflow.com/questions/66329605/…
【解决方案2】:

你可能对django_polymorphic感兴趣

来自项目文档的示例:

当我们存储继承自 Project 模型的模型时...

>>> Project.objects.create(topic="Department Party")
>>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner")
>>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")

...想要检索我们所有的项目,返回子类模型:

>>> Project.objects.all()
[ <Project:         id 1, topic "Department Party">,
  <ArtProject:      id 2, topic "Painting with Tim", artist "T. Turner">,
  <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-23
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多