tags:

views:

422

answers:

3

Is there any Django function which will let me get an object form the database, or None if nothing matches?

Right now I'm using something like:

foo = Foo.objects.filter(bar=baz)
foo = len(foo) > 0 and foo.get() or None

But that's not very clear, and it's messy to have everywhere.

+8  A: 

I'd do

try:
    foo = Foo.objects.get(bar=baz)
except Foo.DoesNotExist:
    foo = None

Which is clearer but longer

Easy enough to wrap into a function

def get_or_none(model, **kwargs):
    try:
        return model.objects.get(**kwargs)
    except model.DoesNotExist:
        return None

Call it like this

foo = get_or_none(Foo, baz=bar)
Nick Craig-Wood
You mean `"except model.DoesNotExist"`.
Glenn Maynard
Yes, just fixed it thanks
Nick Craig-Wood
+4  A: 

Give Foo its custom manager. It's pretty easy - just put your code into function in custom manager, set custom manager in your model and call it with Foo.objects.your_new_func(...).

If you need generic function (to use it on any model not just that with custom manager) write your onw and place it somewhere on your python path and import, not messy any more.

sorki
+3  A: 

To add some sample code to sorki's answer (I'd add this as a comment, but this is my first post, and I don't have enough reputation to leave comments), I implemented a get_or_none custom manager like so:

from django.db import models

class GetOrNoneManager(models.Manager):
    """Adds get_or_none method to objects
    """
    def get_or_none(self, **kwargs):
        try:
            return self.get(**kwargs)
        except self.model.DoesNotExist:
            return None

class Person(models.Model):
    name = models.CharField(max_length=255)
    objects = GetOrNoneManager()

And now I can do this:

bob_or_none = Person.objects.get_or_none(name='Bob')
kaapstorm
Ah, nice. Thanks.
David Wolever