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?
Ich denke, es ist keine schlechte Idee, get_object_or_404()
zu verwenden
from django.shortcuts import get_object_or_404
def my_view(request):
my_object = get_object_or_404(MyModel, pk=1)
Das Beispiel entspricht:
from django.http import Http404
def my_view(request):
try:
my_object = MyModel.objects.get(pk=1)
except MyModel.DoesNotExist:
raise Http404("Kein MyModel entspricht der angegebenen Abfrage.")
Sie können mehr über get_object_or_404() in der Online-Dokumentation von Django lesen.
Von Django 1.7 an können Sie Folgendes tun:
class MyQuerySet(models.QuerySet):
def get_or_none(self, **kwargs):
try:
return self.get(**kwargs)
except self.model.DoesNotExist:
return None
class MyBaseModel(models.Model):
objects = MyQuerySet.as_manager()
class MyModel(MyBaseModel):
...
class AnotherMyModel(MyBaseModel):
...
Der Vorteil von "MyQuerySet.as_manager()" ist, dass beide der folgenden Möglichkeiten funktionieren werden:
MyModel.objects.filter(...).get_or_none()
MyModel.objects.get_or_none()
Ich verwende Django 2.2.16. Und so löse ich dieses Problem:
from typing import Any
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.db.models.base import ModelBase
from django.db.models.manager import Manager
class SManager(Manager):
def get_if_exist(self, *args: Any, **kwargs: Any):
try:
return self.get(*args, **kwargs)
except ObjectDoesNotExist:
return None
class SModelBase(ModelBase):
def _prepare(cls):
manager = SManager()
manager.auto_created = True
cls.add_to_class("objects", manager)
super()._prepare()
class Meta:
abstract = True
class SModel(models.Model, metaclass=SModelBase):
managers = False
class Meta:
abstract = True
Und danach müssen Sie in jedem Modell nur noch folgendes importieren:
from custom.models import SModel
class SUser(SModel):
pass
Und in views
können Sie es so aufrufen:
SUser.objects.get_if_exist(id=1)
Dies ist ein Copycat von Django's get_object_or_404
, ausgenommen davon, dass die Methode None zurückgibt. Dies ist äußerst nützlich, wenn wir nur bestimmte Felder mit der only()
-Abfrage abrufen müssen. Diese Methode kann ein Model oder ein Queryset akzeptieren.
from django.shortcuts import _get_queryset
def get_object_or_none(klass, *args, **kwargs):
"""
Verwenden Sie get(), um ein Objekt zurückzugeben, oder geben Sie None zurück, wenn das Objekt nicht existiert.
Klass kann ein Model, Manager oder QuerySet-Objekt sein. Alle anderen übergebenen Argumente und Schlüsselwortargumente werden für die Abfrage mit get() verwendet.
Wie bei QuerySet.get() wird MultipleObjectsReturned ausgelöst, wenn mehr als ein Objekt gefunden wird.
"""
queryset = _get_queryset(klass)
if not hasattr(queryset, 'get'):
klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
raise ValueError(
"Das erste Argument von get_object_or_none() muss ein Model, Manager oder QuerySet sein, nicht '%s'." % klass__name
)
try:
return queryset.get(*args, **kwargs)
except queryset.model.DoesNotExist:
return None
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.