Existe-t-il une fonction Django qui me permette d'obtenir un objet de la base de données ou Aucune si rien ne correspond?
En ce moment, j'utilise quelque chose comme:
foo = Foo.objects.filter(bar=baz)
foo = len(foo) > 0 and foo.get() or None
Mais ce n'est pas très clair et c'est un désordre d'avoir partout.
Dans Django 1.6 , vous pouvez utiliser la méthode first()
Queryset. Il retourne le premier objet correspondant au queryset, ou None s'il n'y a pas d'objet correspondant.
Usage:
p = Article.objects.order_by('title', 'pub_date').first()
Il y a deux façons de faire ça;
try:
foo = Foo.objects.get(bar=baz)
except model.DoesNotExist:
foo = None
Ou vous pouvez utiliser un wrapper:
def get_or_none(model, *args, **kwargs):
try:
return model.objects.get(*args, **kwargs)
except model.DoesNotExist:
return None
Appelez ça comme ça
foo = get_or_none(Foo, baz=bar)
Pour ajouter un exemple de code à la réponse de sorki (j'ajouterais cela sous forme de commentaire, mais il s'agit de mon premier message et je n'ai pas assez de réputation pour laisser des commentaires), j'ai mis en place un gestionnaire personnalisé get_or_none comme suit:
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()
Et maintenant je peux faire ça:
bob_or_none = Person.objects.get_or_none(name='Bob')
Vous pouvez également essayer d'utiliser Django ennuyeux (il a une autre fonction utile!)
installez-le avec:
pip install Django-annoying
from annoying.functions import get_object_or_None
get_object_or_None(Foo, bar=baz)
Donnez Foo son gestionnaire personnalisé . C'est assez facile - il suffit de mettre votre code en fonction dans le gestionnaire personnalisé, de définir le gestionnaire personnalisé dans votre modèle et de l'appeler avec Foo.objects.your_new_func(...)
.
Si vous avez besoin d’une fonction générique (pour l’utiliser sur n’importe quel modèle et pas seulement avec un gestionnaire personnalisé), écrivez la vôtre et placez-la quelque part sur votre chemin python, puis importez-la.
Que vous le fassiez via un gestionnaire ou une fonction générique, vous pouvez également capturer 'MultipleObjectsReturned' dans l'instruction TRY, car la fonction get () le soulève si votre kwargs récupère plusieurs objets.
Construire sur la fonction générique:
def get_unique_or_none(model, *args, **kwargs):
try:
return model.objects.get(*args, **kwargs)
except (model.DoesNotExist, model.MultipleObjectsReturned), err:
return None
et dans le manager:
class GetUniqueOrNoneManager(models.Manager):
"""Adds get_unique_or_none method to objects
"""
def get_unique_or_none(self, *args, **kwargs):
try:
return self.get(*args, **kwargs)
except (self.model.DoesNotExist, self.model.MultipleObjectsReturned), err:
return None