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?

7voto

Mohammad Reza Punkte 605

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.

5voto

blhsing Punkte 77842

Wenn Sie eine einfache Einstzeiler-Lösung wünschen, die keine Ausnahmebehandlung, bedingten Anweisungen oder einen Bedarf an Django 1.6+ beinhaltet, tun Sie stattdessen dies:

x = next(iter(SomeModel.objects.filter(foo='bar')), None)

3voto

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()

0 Stimmen

Manchmal sind die besten Antworten nicht die am meisten hochgewerteten <3

3voto

Sihc Punkte 51

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)

2voto

Sandeep Balagopal Punkte 1844

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.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