如何使用get_object_or_404排除结果?

goo*_*orp 15 python django orm

在Django中,您可以使用exclude来创建类似于的SQL not equal.一个例子可能是.

Model.objects.exclude(status='deleted')
Run Code Online (Sandbox Code Playgroud)

现在这很好用,排除非常灵活.由于我有点懒,我想在使用时获得该功能get_object_or_404,但我还没有找到办法,因为你不能使用exclude on get_object_or_404.

我想要做的是这样的事情:

model = get_object_or_404(pk=id, status__exclude='deleted')
Run Code Online (Sandbox Code Playgroud)

但不幸的是,这不起作用,因为没有排除查询过滤器或类似.到目前为止,我提出的最好的是做这样的事情:

object = get_object_or_404(pk=id)
if object.status == 'deleted':
    return HttpResponseNotfound('text')
Run Code Online (Sandbox Code Playgroud)

做这样的事情,真的打败了使用点get_object_or_404,因为它不再是一个方便的单行.

或者我可以这样做:

object = get_object_or_404(pk=id, status__in=['list', 'of', 'items'])
Run Code Online (Sandbox Code Playgroud)

但这不会很难维护,因为我需要更新列表.

我想知道我是否在django中缺少某些技巧或功能get_object_or_404来获得所需的结果?

int*_*jay 18

用途django.db.models.Q:

from django.db.models import Q

model = get_object_or_404(MyModel, ~Q(status='deleted'), pk=id)
Run Code Online (Sandbox Code Playgroud)

除了AND之外,Q对象还允许您(不带~运算符)和OR(带|运算符).

请注意,Q对象必须在之前pk=id,因为关键字参数必须在Python中排在最后.


Luc*_*ike 9

最常见的用例是传递模型.但是,您也可以传递QuerySet实例:

queryset = Model.objects.exclude(status='deleted')
get_object_or_404(queryset, pk=1)
Run Code Online (Sandbox Code Playgroud)

Django docs示例:https: //docs.djangoproject.com/en/1.10/topics/http/shortcuts/#id2

  • 我认为这比接受的答案更容易遵循解决方案。我的意思是,如果我正在查看 6 个月前的代码,如果我使用 Q 对象而不是使用排除进行过滤,我会想打自己的脸。 (2认同)