如何在get_object_or_404中排除结果?
在Django中,你可以使用exclude来创建类似于不等于
的SQL查询。比如说,下面这个例子:
Model.objects.exclude(status='deleted')
这个方法效果很好,而且exclude非常灵活。不过因为我有点懒,我希望在使用get_object_or_404
的时候也能有这样的功能,但我找不到办法,因为在get_object_or_404
上不能使用exclude。
我想做的事情大概是这样的:
model = get_object_or_404(pk=id, status__exclude='deleted')
但不幸的是,这样做不行,因为没有exclude查询过滤器或者类似的东西。我目前想到的最好办法是这样:
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
得到想要的结果呢?
4 个回答
还有一种方法可以替代使用 Q 对象。你可以不把模型传给 get_object_or_404
,而是直接把查询集(QuerySet)传给这个函数:
model = get_object_or_404(MyModel.objects.filter(pk=id).exclude(status='deleted'))
不过这样做有一个副作用,就是如果查询集返回了多个结果,它会抛出一个 MultipleObjectsReturned
的异常。
最常见的用法是传递一个模型(Model)。不过,你也可以传递一个查询集(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
from django.db.models import Q
model = get_object_or_404(MyModel, ~Q(status='deleted'), pk=id)
Q对象让你可以使用 NOT(用 ~
操作符)和 OR(用 |
操作符),除了 AND 之外。
需要注意的是,Q对象必须放在 pk=id
之前,因为在Python中,关键字参数必须放在最后。