简体   繁体   English

Django QuerySet-如何“禁用”先前的过滤值

[英]Django QuerySet - How to “disable” previous filtered value

I have a base model class that creates history of an object each time the objects has been changed. 我有一个基础模型类,每次更改对象时都会创建对象的历史记录。 The model has field named 'is_history'. 该模型具有名为“ is_history”的字段。 The idea is that a new instance of the model is created with the old data each time the model has been changed by someone. 这个想法是,每次有人更改模型时,都会使用旧数据创建模型的新实例。 The new model with the old data has 'is_history=True' because becomes history object. 具有旧数据的新模型具有“ is_history = True”的特征,因为它成为历史对象。 In the default admin changelist I do not want to see the history objects. 在默认的管理员更改列表中,我不想查看历史记录对象。 I do not want to see them anywhere by default. 我不想默认情况下在任何地方看到它们。 Thats why i created new manager that overwrites the default get_query_set() and adds 'is_history=False'. 那就是为什么我创建了一个新的管理器,该管理器将覆盖默认的get_query_set()并添加“ is_history = False”。

def get_query_set(self):
    qs = super(ModelHistoryManager, self).get_query_set()
    return qs.filter(is_history=False)

But I also should be able to show the history objects in the changelist view rarely, using admin filter for example. 但是我也应该能够在变更列表视图中很少显示历史对象,例如使用管理过滤器。

My question is: I have a queryset that has already filtered this value. 我的问题是:我有一个已经过滤了此值的查询集。 But in the admin's filter I get the filtered queryset from the base manager and I want to change this filter from is_history=False to is_history=True, or to remove the filter for 'is_history' if the user wants to show all records - both history and original records. 但是在管理员的过滤器中,我从基本管理器中获取了过滤后的查询集,并且我想将此过滤器从is_history = False更改为is_history = True,或者如果用户希望显示所有记录,则删除“ is_history”的过滤器-两个历史记录和原始记录。

Any idea? 任何想法?

Let me quote the django Docs about Custom Managers : 让我引用有关自定义管理器的django文档:

If you use custom Manager objects, take note that the first Manager Django encounters (in the order in which they're defined in the model) has a special status. 如果使用自定义Manager对象,请注意,第一个Django Django遇到的Manager(按在模型中定义的顺序)具有特殊的状态。 Django interprets the first Manager defined in a class as the “default” Manager, and several parts of Django (including dumpdata) will use that Manager exclusively for that model. Django将类中定义的第一个Manager解释为“默认” Manager,并且Django的某些部分(包括dumpdata)将对该模型专用。 As a result, it's a good idea to be careful in your choice of default manager in order to avoid a situation where overriding get_query_set() results in an inability to retrieve objects you'd like to work with. 因此,最好谨慎选择默认管理器,以避免覆盖get_query_set()导致无法检索要使用的对象的情况。

So, you should do something like: 因此,您应该执行以下操作:

class MyModel(Model):
    objects = models.Manager() # The default manager.
    custom_manager = MyCustomManager() # This has overrided the get_query_set method

Of course, you should use custom_manager instead of objects if you want the filtered model instances 当然,如果要过滤的模型实例,则应使用custom_manager而不是objects

You can hack it , but let me warn you that, this is a very bad idea and touches internals not meant to be touched by users. 您可以破解它 ,但是让我警告您,这是一个非常糟糕的主意,并且触及了用户不希望触及的内部结构。 But if you insist, this would do the trick: 但是,如果您坚持要这样做,那将达到目的:

from django.db.models.sql.where import WhereNode
qs.query.where = WhereNode()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM