2012-11-28 70 views
2

我怎么能覆盖,我已经考虑多到许多领域的模型管理器执行以下操作:Django的,覆盖多到许多领域的ModelManager

class TermsManager(models.Manager): 
    def all(self): 
     return super(TermsManager, self).all().filter(condition_here) 


class Term(models.Model): 
    objects = TermsManager() 

    name = models.CharField(max_length=255) 

class Object(models.Model):   
    title = models.CharField(max_length=255) 
    terms = models.ManyToManyField(Term, blank=True) 

class Channel(Object): 
    class Meta: 
     proxy = True 

我也有从继承的类TermManager称为ChannelTermManager。 如何覆盖Channel模型的“terms”字段,以便 mychannel.terms调用ChannelTermManager而不是TermManager?

回答

2

首先,你不应该压倒all()。如果要更改默认查询集,覆盖get_query_set像这样:

class TermsManager(models.Manager): 
    def get_query_set(self): 
     return super(TermsManager, self).get_query_set().filter(condition_here) 

这是因为all()当其他查询集功能链接上经常被忽略,并希望您的查询集有同样的表现all()是否被显式调用或不。

但即便如此,你在做什么仍然是有问题的。如documentation for managers中所述,过滤默认相关查询集将影响幕后的各种自动事物(例如,在转储数据以创建备份/固定装置等时)。 你几乎肯定不想要这个。而且你真的不希望你的相关对象管理者这样做(通过设置use_for_related_fields = True),因为你将屏蔽实际存储在数据库中的内容,而不是简单地检测过时数据并创建警报或其他任何方法来清理它。 use_for_related_fields旨在创造经理,增强了香草经理的正常功能,而不是过滤。

我也有类似的情况,你不过了,我来处理它,像这样:

class FilteredTermsManager(models.Manager): 
    def get_query_set(self): 
     return super(TermsManager, self).get_query_set().filter(condition_here) 

class Term(models.Model): 
    allTerms = models.Manger() # Establish this as the default/automatic manager 
    objects = FilteredTermsManager() 

    name = models.CharField(max_length=255) 

这样一来,我可以通过我的过滤的queryset做模型的所有我的初步查询,它看起来像“定期Django“,但所有关系和幕后查询都可以在未过滤的数据库上工作。而且我总是可以通过手动执行Term.allTerms.all()来访问真正的全套对象。

至于使用不同的管理人员为不同的相关对象,这里没有什么可以真正做到的。但为什么不只是将Channel特定对象添加到您的自定义管理器中,并且根本就不会通过使用从Object获取Term查询集的方法调用它们?

+0

这很有趣。但是,解决方案不会削减它。我的Object的实现是提供其他应用程序可以扩展的EAV模式。一个例子是从对象EAV延伸出来的Channel类。我正在过滤模型管理器中的数据,因为我需要每个类将其自己的类型定义为属性...例如,Channel类定义object_type属性='channel'。术语是定义taxonomy_type的类别的EAV。 – Maverick

+0

现在发生的是,当django admin访问channelObj.terms时,TermManager将taxonomy_type添加到它定义其值为“Category”的查询中。但是,我希望channelObj.terms通过ChannelTerm,因为ChannelTerm将类别分类定义为'channel-category'而不是'category',就像TermManager一样。所以我无法控制django管理员调用哪个管理器来获取任何给定模型的查询集。你怎么看? – Maverick

+0

我不是很了解你在找什么,所以我只能抛出一些想法。您可能想要查看抽象模型继承与内容类型框架的结合。或者,这可能对您有用:http://jeffelmore.org/2010/11/11/automatic-downcasting-of-inherited-models-in-django/ – acjay