不要在CustomManager.get_query_set()中过滤!但是all(),get(),filter(),exclude()呢?

时间:2022-09-02 15:17:26

django's manager docs has a paragraph overwritten with DO NOT FILTER AWAY ANY RESULTS IN THIS TYPE OF MANAGER SUBCLASS, but in the following text only mentions get_query_set()

django的经理文档有一段被覆盖,请勿过滤掉这种类型的经理子类中的任何结果,但在下文中只提到get_query_set()

Is it save to filter in all(), get(), filter(), exclude()?

是否保存过滤all(),get(),filter(),exclude()?

The reason why I want to do that: I want for the automatic Manager as it gives my the power to control, what rows are send to a template-tag as described in b-list: Write better template tags

我想要这样做的原因是:我想要自动管理器,因为它赋予我控制权,将哪些行发送到模板标签,如b-list中所述:编写更好的模板标签

Would this code be OK?

这段代码可以吗?

class ArticleMananger(models.Manager):
    def get_query_set(self):
        return super(ArticleMananger, self).get_query_set()
    def all(self): 
        return super(ArticleMananger, self).filter(published=True)   
    def filter(self,  **kwargs):
        return super(ArticleMananger, self).filter(published=True).filter(**kwargs) 
    .... 

Edit: If someone votes down, it would be nice or just fair to explain why. What is wrong about this question?

编辑:如果有人投票,那么解释原因会很好或公平。这个问题有什么问题?

3 个解决方案

#1


I think, this is a warning only to not override the method get_query_set() in your models.Manager subclass without further consideration of the use of this method by Django itself if this manager gets the default (objects) manager of your model. You might experience hard to debug behavior otherwise.

我想,这只是一个警告,只是在你的models.Manager子类中没有覆盖方法get_query_set()而没有进一步考虑Django本身使用这个方法,如果这个管理器得到模型的默认(对象)管理器的话。否则您可能会遇到难以调试的行为。

Try to add print statements to your overridden methods to see when and how often they are used by other apps (i.e. the admin app).

尝试将print语句添加到被覆盖的方法,以查看其他应用程序(即管理应用程序)使用它们的时间和频率。

#2


The basic idea is that if you change the way the default manager for your model retrieves objects in common methods like all() or filter(), you will eventually run into a situation where you want to retrieve some particular object but can't. Often this will be difficult to diagnose because it'll turn up as objects mysteriously not appearing, or DoesNotExist exceptions where you didn't expect them.

基本思想是,如果更改模型的默认管理器以常用方法(如all()或filter())检索对象的方式,最终会遇到要检索某个特定对象但不能检索的特定对象的情况。通常这很难诊断,因为它会在神秘地出现时出现,或者在你没有预料到的情况下会出现例外情况。

So long as you keep a default manager around that can retrieve everything normally, it's fine to do custom stuff in other managers on the same class, though.

只要保留一个默认管理器可以正常检索所有内容,就可以在同一个类的其他管理器中执行自定义操作。

#3


I did some test and will answer my own question:

我做了一些测试,并将回答我自己的问题:

Do not filter in all(),... too!

I just tried it out. It breaks parts of the admin interface. From a technical point of view it could be possible to overwrite / extend template/admin/apps/* to use another manager (ie via own tags), but I come to the conclusion, that it wont worth the work. Instead I will rewrite my tags to something like this:

我刚试了一下。它会破坏管理界面的一部分。从技术角度来看,有可能覆盖/扩展template / admin / apps / *以使用另一个管理器(即通过自己的标签),但我得出结论,它不值得工作。相反,我会将我的标签重写为以下内容:

def render(self, context):
    if hasattr(self.model, 'publicmgr'):
        context[self.varname] = self.model.publicmgr.all().order_by(self.by)[:self.num]
    else:
        context[self.varname] =   self.model._default_manager.all().order_by(self.by)[:self.num]
    return  ''

#1


I think, this is a warning only to not override the method get_query_set() in your models.Manager subclass without further consideration of the use of this method by Django itself if this manager gets the default (objects) manager of your model. You might experience hard to debug behavior otherwise.

我想,这只是一个警告,只是在你的models.Manager子类中没有覆盖方法get_query_set()而没有进一步考虑Django本身使用这个方法,如果这个管理器得到模型的默认(对象)管理器的话。否则您可能会遇到难以调试的行为。

Try to add print statements to your overridden methods to see when and how often they are used by other apps (i.e. the admin app).

尝试将print语句添加到被覆盖的方法,以查看其他应用程序(即管理应用程序)使用它们的时间和频率。

#2


The basic idea is that if you change the way the default manager for your model retrieves objects in common methods like all() or filter(), you will eventually run into a situation where you want to retrieve some particular object but can't. Often this will be difficult to diagnose because it'll turn up as objects mysteriously not appearing, or DoesNotExist exceptions where you didn't expect them.

基本思想是,如果更改模型的默认管理器以常用方法(如all()或filter())检索对象的方式,最终会遇到要检索某个特定对象但不能检索的特定对象的情况。通常这很难诊断,因为它会在神秘地出现时出现,或者在你没有预料到的情况下会出现例外情况。

So long as you keep a default manager around that can retrieve everything normally, it's fine to do custom stuff in other managers on the same class, though.

只要保留一个默认管理器可以正常检索所有内容,就可以在同一个类的其他管理器中执行自定义操作。

#3


I did some test and will answer my own question:

我做了一些测试,并将回答我自己的问题:

Do not filter in all(),... too!

I just tried it out. It breaks parts of the admin interface. From a technical point of view it could be possible to overwrite / extend template/admin/apps/* to use another manager (ie via own tags), but I come to the conclusion, that it wont worth the work. Instead I will rewrite my tags to something like this:

我刚试了一下。它会破坏管理界面的一部分。从技术角度来看,有可能覆盖/扩展template / admin / apps / *以使用另一个管理器(即通过自己的标签),但我得出结论,它不值得工作。相反,我会将我的标签重写为以下内容:

def render(self, context):
    if hasattr(self.model, 'publicmgr'):
        context[self.varname] = self.model.publicmgr.all().order_by(self.by)[:self.num]
    else:
        context[self.varname] =   self.model._default_manager.all().order_by(self.by)[:self.num]
    return  ''