2017-02-15 18 views
2

我的模型,看起来像这样:Django的让所有的基类对象,他们的派生类中有一个混合

class SomeModel(model.Model): 
    pass 


class Base(models.Model): 
    field1 = ... 


class Mixin1(models.Model): 
    some_model = models.ForeignKey('SomeModel', on_delete=models.CASCADE) 

    class Meta: 
     abstract = True 


class Derive1(Base, Mixin1): 
    field2 = ... 


class Derive2(Base, Mixin1): 
    field3 = ... 


class Derive3(Base): 
    field4 = ... 

现在我希望能够得到来自BaseMixin1派生的所有对象,不明确列出使用Mixin1的所有类。 喜欢的东西:

Base.objects.filter(some_model=X) 

为什么这不工作,我理解,但如何实际让它工作,我不知道。

解决方案:感谢valentjedi's answer我得到了一个工作解决方案。我在这里发布它,以防某天某个人帮助某人。

在想组合的结果的顶部,我也希望他们在基础日期字段,并自由地过滤他们的能力进行排序。所以,我在Mixin1创建的函数:

@staticmethod 
def get_mixin1_objects(some_model, q_filter=None): 
    mixin_models = set(Mixin1.__subclasses__()) & set(Base.__subclasses__()) 
    results = [] 
    for mdl in mixin_models: 
     apply_filter = Q(some_model=some_model) 
     if q_filter is not None: 
      apply_filter &= q_filter 
     results.append(list(mdl.objects.filter(apply_filter).order_by('date').all())) 

    # Merge sort all the events 
    return list(heapq.merge(*results)) 

同时加入到基材的制备方法:

def __gt__(self, other): 
    return self.date > other.date 

因此我可以使用过滤器,但是我喜欢,并能得到order_by恒定场的结果(这足够我目前的需求)。用法

例子:

lst = Mixinq.get_mixin1_objects(some_model_instance, q_filter=~Q(some_field_in_base=some_value)) 
+0

如果派生类不添加任何属性,您曾经考虑过代理模型的方法呢? https://docs.djangoproject.com/en/1.10/topics/db/models/#proxy-models – abrunet

+0

我虽然使用所有类中的字段。编辑了这个问题。 –

回答

3

我可能不明白你的问题清楚,但可以使用__subclasses__魔法方法是这样的:

>>> set(Mixin1.__subclasses__()) & set(Base.__subclasses__()) 
{Derive2, Derive1} 

然后你就可以过滤这些模型做无论你想要他们。

+0

假设我这样做,我需要再上运行集合中的每个所产生的模型的查询来获取相关的外键我想通过搜索所有对象? –

+0

是的,它的好处是你会得到正确的正确实例,例如'Derive1'和'Derive2'而不是'Base' – valignatev

+0

这个问题是我失去了QuerySet的功能。在Django 1.11应该是[qs.union(http://stackoverflow.com/a/42186970/5019818) - 但在此期间,这将需要做的 - 因此作为标记正确答案 –

相关问题