410 Stimmen

Wie erhalte ich das Objekt, wenn es existiert, oder None, wenn es in Django nicht existiert?

Wenn ich den Modelmanager bitte, ein Objekt zu erhalten, wird DoesNotExist ausgelöst, wenn kein passendes Objekt vorhanden ist.

go = Content.objects.get(name="baby")

Anstatt DoesNotExist, wie kann ich stattdessen go None haben?

537voto

Arthur Debert Punkte 9426

Es gibt keinen 'eingebauten' Weg, dies zu tun. Django wird die DoesNotExist Ausnahme jedes Mal auslösen. Der idiomatische Weg, dies in Python zu behandeln, besteht darin, es in einen Try-Catch-Block zu verpacken:

try:
    go = SomeModel.objects.get(foo='bar')
except SomeModel.DoesNotExist:
    go = None

Was ich getan habe, ist, models.Manager zu unterklassen, ein safe_get wie den obigen Code zu erstellen und diesen Manager für meine Modelle zu verwenden. Auf diese Weise können Sie schreiben: SomeModel.objects.safe_get(foo='bar').

10 Stimmen

Schöne Verwendung von SomeModel.DoesNotExist anstelle des Imports der Ausnahme.

313 Stimmen

Diese Lösung ist vier Zeilen lang. Für mich ist das zu viel. Mit django 1.6 können Sie SomeModel.objects.filter(foo='bar').first() verwenden. Dies gibt das erste übereinstimmende Element zurück oder None. Es schlägt nicht fehl, wenn es mehrere Instanzen gibt wie queryset.get()

32 Stimmen

Ich denke, es ist schlechter Stil, Ausnahmen für die Behandlung von Standardfällen übermäßig zu verwenden. Ja, "es ist einfacher um Vergebung zu bitten als um Erlaubnis". Aber Ausnahmen sollten meiner Meinung nach dennoch nur für Ausnahmefälle verwendet werden.

342voto

FeroxTL Punkte 4248

Ab Django 1.6 können Sie die first() Methode folgendermaßen verwenden:

Content.objects.filter(name="baby").first()

Wenn keine Objekte den Kriterien entsprechen, wird None zurückgegeben. Wenn mehr als ein Objekt den Kriterien entspricht, wird das erste übereinstimmende zurückgegeben (kein Fehler wird ausgelöst).

60 Stimmen

In diesem Fall wird kein Fehler gemeldet, wenn es mehr als eine Übereinstimmung gibt.

2 Stimmen

Ich mag diese Lösung, weil die Verwendung von objecst.get() darauf schließen lässt, dass wir wissen, dass es entweder eins oder keins in der Datenbank gibt.

10 Stimmen

'FeroxTL' du musst @guettli für diese Antwort anerkennen, da er diesen Kommentar ein Jahr vor deinem Beitrag auf die akzeptierte Antwort abgegeben hat.

61voto

Ranju R Punkte 2117

Sie können eine generische Funktion dafür erstellen.

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

Verwenden Sie es wie folgt:

go = get_or_none(Content,name="baby")

go wird None sein, wenn kein Eintrag übereinstimmt, ansonsten wird der Content-Eintrag zurückgegeben.

Hinweis: Es wird eine Ausnahme MultipleObjectsReturned ausgelöst, wenn mehr als ein Eintrag für name="baby" zurückgegeben wird.

Sie sollten dies im Datenmodell behandeln, um diese Art von Fehler zu vermeiden, aber Sie können es auch zur Laufzeit protokollieren, wie hier:

def get_or_none(classmodel, **kwargs):
    try:
        return classmodel.objects.get(**kwargs)
    except classmodel.MultipleObjectsReturned as e:
        print('ERR====>', e)

    except classmodel.DoesNotExist:
        return None

0 Stimmen

Großartig! Wenn es sich um einen Client-Seitenfehler handelt: von django.shortcuts import get_object_or_404 ansonsten ist es ein Serverseitenproblem, daher ist get_or_none das Beste.

53voto

Amarghosh Punkte 56804

Aus den Django-Dokumenten

get() löst eine DoesNotExist-Ausnahme aus, wenn ein Objekt mit den angegebenen Parametern nicht gefunden wird. Diese Ausnahme ist auch ein Attribut der Modellklasse. Die DoesNotExist-Ausnahme erbt von django.core.exceptions.ObjectDoesNotExist

Sie können die Ausnahme abfangen und None zu go zuweisen.

from django.core.exceptions import ObjectDoesNotExist
try:
    go  = Content.objects.get(name="baby")
except ObjectDoesNotExist:
    go = None

26voto

Gaurav Punkte 963

Sie können es auf diese Weise tun:

 gehen = Content.objects.filter(name="baby").first()

Jetzt kann die gehen Variable entweder das gewünschte Objekt oder None sein

Ref: https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.first

5 Stimmen

Aber... Dies ist dieselbe Antwort wie oben von @FeroxTL

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X