2017-02-15 19 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) - 但在此期間,這將需要做的 - 因此作爲標記正確答案 –

相關問題