googletorp googletorp - 1 year ago 42
Python Question

How to exclude results with get_object_or_404?

In Django you can use the exclude to create SQL similar to

not equal
. An example could be.


Now this works great and exclude is very flexible. Since I'm a bit lazy, I would like to get that functionality when using
, but I haven't found a way to do this, since you cannot use exclude on

What I want is to do something like this:

model = get_object_or_404(pk=id, status__exclude='deleted')

But unfortunately this doesn't work as there isn't an exclude query filter or similar. The best I've come up with so far is doing something like this:

object = get_object_or_404(pk=id)
if object.status == 'deleted':
return HttpResponseNotfound('text')

Doing something like that, really defeats the point of using
, since it no longer is a handy one-liner.

Alternatively I could do:

object = get_object_or_404(pk=id, status__in=['list', 'of', 'items'])

But that wouldn't be very maintainable, as I would need to keep the list up to date.

I'm wondering if I'm missing some trick or feature in django to use
to get the desired result?

Answer Source

Use django.db.models.Q:

from django.db.models import Q

model = get_object_or_404(MyModel, ~Q(status='deleted'), pk=id)

The Q objects lets you do NOT (with ~ operator) and OR (with | operator) in addition to AND.

Note that the Q object must come before pk=id, because keyword arguments must come last in Python.