如何使用get_object_or_404排除结果?
在Django中,您可以使用排除来创建类似于not equal
的SQL。一个例子可能是。如何使用get_object_or_404排除结果?
Model.objects.exclude(status='deleted')
现在这个工程很好,排除非常灵活。由于我有点懒,我想在使用get_object_or_404
时得到这个功能,但我还没找到办法做到这一点,因为你不能在get_object_or_404
上使用排除。
我要的是做这样的事情:
model = get_object_or_404(pk=id, status__exclude='deleted')
但不幸的是,因为没有一个排除查询过滤器或类似这不起作用。最好的我想出迄今做这样的事情:
object = get_object_or_404(pk=id)
if object.status == 'deleted':
return HttpResponseNotfound('text')
做这样的事情,确实违背了使用get_object_or_404
,因为它不再是一个方便的单行点。
我也可以这样做:
object = get_object_or_404(pk=id, status__in=['list', 'of', 'items'])
但是,这不会很维护,因为我需要保持清单的更新。
我想知道如果我错过了Django的一些技巧或功能使用get_object_or_404
来获得所需的结果?
from django.db.models import Q
model = get_object_or_404(MyModel, ~Q(status='deleted'), pk=id)
将q对象让你不(与~
运营商)和OR(与|
运营商)除了和。
请注意,Q对象必须在pk=id
之前,因为关键字参数必须在Python中持续。
引起Q对象。不知道它会在那场比赛中奏效。感谢名单。 – googletorp 2010-06-15 23:24:42
除了模型之外,您还可以传递Manager或QuerySet作为第一个参数。请参阅http://*.com/a/26476339/336694 – Heliodor 2015-03-11 17:12:03
还有另一种方式,而不是使用Q对象。相反,模型传递到get_object_or_404
的只是通过查询集,而不是功能:这
model = get_object_or_404(MyModel.objects.filter(pk=id).exclude(status='deleted'))
一个副作用,但是,它会提高一个MultipleObjectsReturned
异常,如果查询集返回多个结果。
最常见的用例是传递一个模型。但是,你也可以通过一个QuerySet实例:
queryset = Model.objects.exclude(status='deleted')
get_object_or_404(queryset, pk=1)
Django文档例如: https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#id2
我认为这比接受的答案更容易遵循解决方案。我的意思是,如果我在6个月前查看过我的代码,那么如果我使用Q对象而不是使用排除过滤,我会想让自己在脸上表现出色。 – 2017-03-26 15:28:04
get_object_or_404
利用对象管理的get_queryset
方法。如果您覆盖get_queryset
方法以仅返回未被“删除”的项目,则get_object_or_404
将自动按您的需要运行。然而,像这样覆盖get_queryset
可能会在别处出现问题(可能在管理页面中),但是当您需要访问软删除项目时,您可以添加备用管理器。
from django.db import models
class ModelManger(models.Manger):
def get_queryset(self):
return super(ModelManger, self).get_queryset().exclude(status='deleted')
class Model(models.Model):
# ... model properties here ...
objects = ModelManager()
all_objects = models.Manager()
所以,如果你只需要非删除的项目,你可以做get_object_or_404(Models, id=id)
但如果你需要的所有项目,你可以做get_object_or_404(Models.all_objects, id=id)
。
这不是一个真正的答案,但它似乎不会真的想404软删除对象。软删除的重点是保持对象“以防万一”。 – 2010-06-15 15:07:28