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?
Um es einfacher zu machen, hier ist ein Ausschnitt des Codes, den ich basierend auf den wunderbaren Antworten hier geschrieben habe:
class MyManager(models.Manager):
def get_or_none(self, **kwargs):
try:
return self.get(**kwargs)
except ObjectDoesNotExist:
return None
Und dann in Ihrem Modell:
class MyModel(models.Model):
objects = MyManager()
Das war's. Jetzt haben Sie MyModel.objects.get() sowie MyModel.objetcs.get_or_none()
Das würde einen zusätzlichen Datenbankaufruf verursachen, wenn er existiert. Keine gute Idee.
@Christoffer bin nicht sicher, warum das ein zusätzlicher Datenbankaufruf wäre. Laut den Dokumenten: Hinweis: Wenn Sie nur feststellen möchten, ob mindestens ein Ergebnis vorhanden ist (und die tatsächlichen Objekte nicht benötigen), ist es effizienter, exists() zu verwenden.
@Christoffer Ich denke, du hast recht. Ich lese die Frage jetzt noch einmal und der OP möchte tatsächlich, dass das tatsächliche Objekt zurückgegeben wird. Also wird exists()
mit einer if
-Klausel verwendet, bevor das Objekt abgerufen wird und dadurch einen doppelten Treffer in der Datenbank verursacht. Ich werde den Kommentar trotzdem stehen lassen, falls er jemand anderem hilft.
Es ist eine dieser ärgerlichen Funktionen, die Sie möglicherweise nicht erneut implementieren möchten:
from annoying.functions import get_object_or_None
#...
user = get_object_or_None(Content, name="baby")
Ich habe den Code von get_object_or_None
überprüft, aber festgestellt, dass es immer noch MultipleObjectsReturned
auslöst, wenn mehr als ein Objekt vorhanden ist. Daher sollte der Benutzer möglicherweise eine try-except
-Konstruktion in Betracht ziehen (obwohl die Funktion selbst bereits über ein try-except
verfügt).
Das Bearbeiten von Ausnahmen an verschiedenen Stellen in Ihren Ansichten könnte wirklich umständlich sein.. Was ist mit der Definition eines benutzerdefinierten Model Managers in der models.py-Datei, wie zum Beispiel
class ContentManager(model.Manager):
def get_nicely(self, **kwargs):
try:
return self.get(kwargs)
except(KeyError, Content.DoesNotExist):
return None
und dann fügen Sie es der content Model-Klasse hinzu
class Content(model.Model):
...
objects = ContentManager()
Auf diese Weise kann es in den Ansichten leicht behandelt werden, z.B.
post = Content.objects.get_nicely(pk = 1)
if post:
# Mach etwas
else:
# Dieser Beitrag existiert nicht
Ich mag diese Lösung wirklich, konnte sie aber nicht so zum Laufen bringen, wenn ich Python 3.6 verwendet habe. Wollte einen Hinweis hinterlassen, dass die Änderung des Rückgabewerts im ContentManager zu return self.get(**kwargs)
dazu geführt hat, dass es bei mir funktioniert hat. Nicht dass etwas mit der Antwort falsch wäre, nur ein Tipp für alle, die versuchen, es mit späteren Versionen zu verwenden (oder mit allem anderen, das mich daran gehindert hat, es zum Laufen zu bringen).
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.