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?
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?
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')
.
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()
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.
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).
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.
'FeroxTL' du musst @guettli für diese Antwort anerkennen, da er diesen Kommentar ein Jahr vor deinem Beitrag auf die akzeptierte Antwort abgegeben hat.
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
get()
löst eineDoesNotExist
-Ausnahme aus, wenn ein Objekt mit den angegebenen Parametern nicht gefunden wird. Diese Ausnahme ist auch ein Attribut der Modellklasse. DieDoesNotExist
-Ausnahme erbt vondjango.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
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
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.