Is the DoesNotExist exception the only way to check if an object exists?

701 views
Skip to first unread message

Joakim Hove

unread,
Apr 9, 2010, 5:54:48 PM4/9/10
to Django users
Hello,

I have something I would presume was a very common pattern. I have a
view which gets a primary-key (from the user) as second argument:


def my_view( request , pk ):
obj = Class.objects.get( pk = pk)
# Do something with obj and return a suitable response.


Now, of course I would like to check whether the object identified by
'pk' is in the database, and return a suitable error message if that
fails; I was halfway expecting to find a "has_key() / exists() / ..."
method, but it seems the only way to handle this gracefully is by
catching the DoesNotExist exception?

I have never really got very friendly with exceptions, I tend to
consider them as something exceptional which "should not" happen,
whereas the fact that the database does not contain a particular key
is in my opinion something quite ordinary and not by any means
"exceptional".

Or maybe I am misunderstanding roally here?

Joakim


johan sommerfeld

unread,
Apr 9, 2010, 6:44:19 PM4/9/10
to django...@googlegroups.com
If you don't want to use exception (which I do when doing something similar). You can use filter and then check the length of the array returned. 

def my_view( request , pk ):
    obj = Class.objects.filter( pk = pk)
    if len(obj) != 1:
        return bad_key_view
    obj = obj[0]

    # Do something with obj and return a suitable response.

/J



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.


Tom X. Tobin

unread,
Apr 9, 2010, 6:46:24 PM4/9/10
to django...@googlegroups.com
On Fri, Apr 9, 2010 at 4:54 PM, Joakim Hove <joaki...@gmail.com> wrote:
> I have never really got very friendly with exceptions, I tend to
> consider them as something exceptional which "should not" happen,
> whereas the fact that the database does not contain a particular key
> is in my opinion something quite ordinary and not by any means
> "exceptional".

Exceptions (despite the name) are absolutely *not* "exceptional" in
Python; they're the standard idiom for handling all sorts of things.
The "Pythonic" idea isn't "Look Before You Leap" (check first, then
act); it's instead "Easier to Ask Forgiveness than Permission" (try to
do something, and handle failure if it does happen).

Love your exceptions; they're friendly (and quite useful) beasts.

Kevin Teague

unread,
Apr 9, 2010, 7:30:40 PM4/9/10
to Django users
There is nothing exceptional about exceptions in Python. McDonc does a
good job at explaining how to think about exceptions as less than
exceptional:

http://plope.com/Members/chrism/exceptions_arent_errors/view

The only arguably exceptional part is that ideally the ORM would raise
a plain KeyError exception instead of a custom exception when a key
look-up fails ...

Matt Schinckel

unread,
Apr 10, 2010, 5:46:56 AM4/10/10
to Django users

It makes a difference if you are likely to find an object or not - at
least in terms of performance.

If you are expecting to find an object, (and only one), the setup of a
try: except: clause is minimal, but if you are not finding an object
more often than not, it turns out to be much slower to have the
exception raised.

Having said that, the cost of having two DB queries may overcome that
anyway: len(queryset) followed by queryset.get() is probably going to
hit the database twice. A better solution would be to do a
queryset.all(), see if the length is 1, and then get the first value
by index 0.

Matt.

Daniel Roseman

unread,
Apr 10, 2010, 8:05:32 AM4/10/10
to Django users

Although I agree with the other posts that there isn't anything
exceptional about exceptions in Python, there is a shortcut for
exactly this pattern: get_object_or_404. See the documentation:
http://docs.djangoproject.com/en/dev/topics/http/shortcuts/#get-object-or-404
--
DR.

greatlemer

unread,
Apr 10, 2010, 10:40:12 AM4/10/10
to Django users
This can work when you know you want to use the object once it's been
retrieved. If all you want to do is check for existence then it's
better to do the check with a:

if Class.objects.filter(pk=pk).count() == 0:
# Do object doesn't exist stuff
else:
# Do object does exist stuff

--
G

On Apr 9, 11:44 pm, johan sommerfeld <johan.sommerf...@gmail.com>
wrote:

> > django-users...@googlegroups.com<django-users%2Bunsubscribe@google groups.com>

Reply all
Reply to author
Forward
0 new messages