在Django中获取继承的模型对象

8 投票
4 回答
4064 浏览
提问于 2025-04-16 12:52

我有一个django应用,里面有一个这样的模型:

对象A是一个简单的模型,里面有几个字段。比如,有一个叫"NAME"的字符字段和一个叫"ORDER"的整数字段。A是抽象的,这意味着数据库里没有A对象,而是...

对象BCA的具体实现,也就是说它们继承了A,并且添加了一些其他字段。

现在假设我需要找出所有NAME字段以字母"Z"开头的对象,并且按照ORDER字段排序,但我还想要这些对象的所有BC特有的字段。现在我看到两种方法:

a) 分别对BC对象进行查询,获取两个列表,然后合并它们,手动排序,再进行处理。

b) 查询A对象,找出名字以"Z"开头的,并按照"ORDER"排序,然后用这个结果去查询BC对象,以获取所有剩余的数据。

这两种方法听起来都很低效,第一种我得自己排序,第二种我得多次查询数据库。

有没有什么神奇的方法可以一次性获取所有BC对象,并且按顺序排列?或者至少有没有比这两种方法更有效的方式?

谢谢!

布鲁诺

4 个回答

1

这个问题的答案可以在 这里 找到。

可以使用来自 django-model-utils 项目的 InheritanceManager

1

使用你的“b”方法查询,可以让你一次性获取所有剩余的数据,而不需要单独去查询B和C模型。你可以使用“点小写模型名”的关系来实现。

http://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance

for object in A.objects.filter(NAME__istartswith='z').order_by('ORDER'):
    if object.b:
        // do something
        pass
    elif object.c:
        // do something
        pass

你可能需要尝试使用try和except来处理DoesNotExist的异常。我对django有点生疏了,祝你好运。

6

如果A可以具体化的话,你可以通过select_related一次性完成所有查询。

from django.db import connection
q = A.objects.filter(NAME__istartswith='z').order_by('ORDER').select_related('b', 'c')
for obj in q:
   obj = obj.b or obj.c or obj
   print repr(obj), obj.__dict__ # (to prove the subclass-specific attributes exist)
print "query count:", len(connection.queries)

撰写回答