Python 在django中获取继承的模型对象

Python 在django中获取继承的模型对象,python,django,inheritance,model,Python,Django,Inheritance,Model,我有一个django应用程序,其模型如下: 对象A是从模型扩展而来的简单对象,有几个字段,比如说,一个特定的字段是一个名为“NAME”的字符字段和一个名为“ORDER”的整数字段A是抽象的,这意味着数据库中没有A对象,而是 对象B和C是A的专门化,这意味着它们继承自A,并添加了一些其他字段 现在假设我需要所有对象,其字段名称以字母“Z”开头,按顺序字段排序,但我也需要这些对象的所有B和C特定字段。现在我看到两种方法: a) 分别查询B和C对象,获取两个列表,合并它们,手动排序并使用它们 b) 查

我有一个django应用程序,其模型如下:

对象A是从模型扩展而来的简单对象,有几个字段,比如说,一个特定的字段是一个名为“NAME”的字符字段和一个名为“ORDER”的整数字段A是抽象的,这意味着数据库中没有A对象,而是

对象BCA的专门化,这意味着它们继承自A,并添加了一些其他字段

现在假设我需要所有对象,其字段名称以字母“Z”开头,按顺序字段排序,但我也需要这些对象的所有BC特定字段。现在我看到两种方法:

a) 分别查询BC对象,获取两个列表,合并它们,手动排序并使用它们

b) 查询A对象中以“Z”开头的名称按顺序“排序,并根据查询结果查询bC对象以获取所有剩余数据

这两种方法听起来都非常低效,第一种方法我必须自己订购,第二种方法我必须多次查询数据库

有没有一种神奇的方法让我无法取回所有BC对象,它们都是用一种方法排序的?或者至少是一种比上述两种方法更有效的方法

提前谢谢

Bruno

使用“b”方法进行查询,将允许您“引入”所有剩余数据,而无需单独查询b和C模型。您可以使用“点小写模型名”关系


您可能需要尝试并排除DoesNotExist异常。我的django有点生疏了。祝你好运

如果
A
可以是具体的,您可以使用
select\u 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)

只要您对B和C上的两个查询进行排序,就可以相当容易地合并它们,而无需进行昂贵的操作:

# first define a couple of helper functions 

def next_or(iterable, other):
    try:
        return iterable.next(), None
    except StopIteration:
        return None, other

def merge(x,y,func=lambda a,b: a<=b):
    ''' merges a pair of sorted iterables '''
    xs = iter(x)
    ys = iter(y)
    a,r = next_or(xs,ys)
    b,r = next_or(ys,xs)
    while r is None:
        if func(a,b):
            yield a
            a,r = next_or(xs,ys)
        else:
            yield b
            b,r = next_or(ys,xs)
    else:
        if a is not None:
            yield a
        else:
            yield b
    for o in r:
        yield o

# now get your objects & then merge them

b_qs = B.objects.filter(NAME__startswith='Z').order_by('ORDER')
c_qs = C.objects.filter(NAME__startswith='Z').order_by('ORDER')

for obj in merge(b_qs,c_qs,lambda a,b: a.ORDER <= b.ORDER):
    print repr(obj), obj.__dict__
#首先定义两个助手函数
def next_或(iterable,其他):
尝试:
返回iterable.next(),无
除停止迭代外:
不返回任何,其他

def merge(x,y,func=lambda,b:a回答了这个问题


使用项目中的。

欢迎使用Django模型继承。享受(!)您的住宿。是的,您需要捕获
DoesNotExist
,以及每次访问相关对象的尝试(成功与否)将花费您一个额外的查询--非常低效。聪明。可怕,但聪明。当一个是抽象的时不起作用?正确的,具体的多表继承只。我同意Wogan的观点,从概念上讲它很难看,但它就像一个符咒,只要我们能做一个具体的,这对我来说不是一件可怕的事情!非常聪明!
# first define a couple of helper functions 

def next_or(iterable, other):
    try:
        return iterable.next(), None
    except StopIteration:
        return None, other

def merge(x,y,func=lambda a,b: a<=b):
    ''' merges a pair of sorted iterables '''
    xs = iter(x)
    ys = iter(y)
    a,r = next_or(xs,ys)
    b,r = next_or(ys,xs)
    while r is None:
        if func(a,b):
            yield a
            a,r = next_or(xs,ys)
        else:
            yield b
            b,r = next_or(ys,xs)
    else:
        if a is not None:
            yield a
        else:
            yield b
    for o in r:
        yield o

# now get your objects & then merge them

b_qs = B.objects.filter(NAME__startswith='Z').order_by('ORDER')
c_qs = C.objects.filter(NAME__startswith='Z').order_by('ORDER')

for obj in merge(b_qs,c_qs,lambda a,b: a.ORDER <= b.ORDER):
    print repr(obj), obj.__dict__