proposal: update QuerySet.get() to return a default if object does not exist?

23 views
Skip to first unread message

Rob Hudson

unread,
Aug 22, 2007, 3:10:37 AM8/22/07
to Django developers
I did a search and found this thread:
http://groups.google.com/group/django-developers/browse_thread/thread/49a6b99dbcea4364/dbaa965c304feed3

It looks like there was general support for the idea but the thread
died and as far as I can tell there was never any decision or ticket.

Just tonight I found myself writing this a number of times:

category = None
try:
category = Category.objects.get(name=category_name)
except Category.DoesNotExist:
pass

It would be great if get too an argument to return a default value if
the item doesn't exist. I understand this could be tricky if you have
a field named 'default'. Gary Wilson points out a few options which
I'll repeat here:

1) Add a get_or_none() method that returns None if object does not
exist.

2) Add a get_or_default() method that accepts a "default" keyword
argument, the value of which gets returned if object does not exist.
If a default is not specified then None gets returned by default.

3) Modify the current get() method to accept a "default" keyword
argument as in option 2), except that instead of returning None if
"default" is not specified, a DoesNotExist exception is raised like
normal. To return None, you would have to explicitly say
"default=None".


Is it possible to have a keyword argument with a leading underscore?
To me it's not unreasonable to have a reserved column name for this
and validate barks if you try to use it in your models in order for
this to work:

category = Category.objects.get(name=category_name, _default=None)

Cheers!
-Rob

Russell Keith-Magee

unread,
Aug 22, 2007, 7:59:02 PM8/22/07
to django-d...@googlegroups.com
On 8/22/07, Rob Hudson <trebor...@gmail.com> wrote:
>
> I did a search and found this thread:
> http://groups.google.com/group/django-developers/browse_thread/thread/49a6b99dbcea4364/dbaa965c304feed3
>
> It looks like there was general support for the idea but the thread
> died and as far as I can tell there was never any decision or ticket.

At least one of the reasons for the delay will be that we have been
waiting on a refactor of query.py. This refactor has been on the cards
for a while, but Malcolm has said he is going to eschew all other
activity this week until the refactor is done.

So - I would suggest holding off for a week or two (to let the dust
settle on the refactor), and then poke this issue again. For the
record, I think the general idea has merit, we just need to finess
some details.

Yours,
Russ Magee %-)

Adrian Holovaty

unread,
Aug 23, 2007, 2:09:30 AM8/23/07
to django-d...@googlegroups.com
On 8/22/07, Russell Keith-Magee <freakb...@gmail.com> wrote:
> So - I would suggest holding off for a week or two (to let the dust
> settle on the refactor), and then poke this issue again. For the
> record, I think the general idea has merit, we just need to finess
> some details.

Yeah, we should wait until the query.py refactoring is done, but I'm
+1 on this change. It's a pain to have to wrap things in try/excepts
all of the time.

Of the options Rob pointed out, I prefer the last -- giving the get()
method an optional "default" parameter, instead of creating new
methods like get_or_default() or get_or_none(). We can easily get
around the fact that it clashes with fields named "default" -- if you
have a field named "default" and want to do an exact lookup, just use
"default__exact" instead of "default". That seems like a reasonable
solution.

This would be backwards-incompatible for anybody who currently has a
field named "default" and does an exact lookup. But I think that's OK,
as long as we document it and get the word out.

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com

Dan Watson

unread,
Oct 11, 2007, 1:57:20 PM10/11/07
to Django developers
Just to ping this again (since I think it's super-convenient and don't
want it to get lost), I've created ticket 5741 with a patch and doc
changes. The patch would look the same for the queryset-refactor
branch as it stands now, too.

http://code.djangoproject.com/ticket/5741

Dan

On Aug 23, 2:09 am, "Adrian Holovaty" <holov...@gmail.com> wrote:

Joe

unread,
Oct 12, 2007, 8:53:02 AM10/12/07
to Django developers
I don't know how many times I've wanted to to this:

return render_to_response("template.html",
{"object":Model.objects.get(parameter=value)})

instead of that exception handling.

On Aug 23, 2:09 am, "Adrian Holovaty" <holov...@gmail.com> wrote:

Jeremy Dunck

unread,
Oct 12, 2007, 10:31:56 AM10/12/07
to django-d...@googlegroups.com
On 10/12/07, Joe <josep...@gmail.com> wrote:
>
> I don't know how many times I've wanted to to this:
>
> return render_to_response("template.html",
> {"object":Model.objects.get(parameter=value)})
>
> instead of that exception handling.

You want get_object_or_404.
http://www.djangoproject.com/documentation/db-api/#get-object-or-404

Joe

unread,
Oct 15, 2007, 10:59:30 AM10/15/07
to Django developers
Actually, I don't want a 404, just to pass 'None' in as the value for
"object".

On Oct 12, 10:31 am, "Jeremy Dunck" <jdu...@gmail.com> wrote:

Reply all
Reply to author
Forward
0 new messages