답변:
이를위한 '내장'방법은 없습니다. 장고는 매번 DoesNotExist 예외를 발생시킵니다. 파이썬에서 이것을 처리하는 관용적 인 방법은 그것을 시도 캐치로 감싸는 것입니다.
try:
go = SomeModel.objects.get(foo='bar')
except SomeModel.DoesNotExist:
go = None
내가 한 것은 모델을 서브 클래스하는 것입니다 .Manager, safe_get
위의 코드와 같은 코드를 만들고 해당 관리자를 사용하십시오. 그렇게하면 다음과 같이 쓸 수 있습니다 : SomeModel.objects.safe_get(foo='bar')
.
SomeModel.objects.filter(foo='bar').first()
에서는 첫 번째 일치를 반환하거나 None을 사용할 수 있습니다 . 여러 인스턴스가 같이있는 경우는 실패하지 않습니다queryset.get()
filter().first()
예외는 갈 길이라고 생각합니다.
django 1.6부터 first () 메소드를 다음과 같이 사용할 수 있습니다 .
Content.objects.filter(name="baby").first()
get()
DoesNotExist
주어진 매개 변수에 대해 개체를 찾을 수 없으면 예외 가 발생합니다. 이 예외는 모델 클래스의 속성이기도합니다.DoesNotExist
에서 예외 상속django.core.exceptions.ObjectDoesNotExist
예외를 잡아서 None
갈 수 있습니다.
from django.core.exceptions import ObjectDoesNotExist
try:
go = Content.objects.get(name="baby")
except ObjectDoesNotExist:
go = None
이를위한 일반 함수를 만들 수 있습니다.
def get_or_none(classmodel, **kwargs):
try:
return classmodel.objects.get(**kwargs)
except classmodel.DoesNotExist:
return None
아래와 같이 사용하십시오 :
go = get_or_none(Content,name="baby")
일치하는 항목이 없으면 go는 None이되며 Content 항목을 반환합니다.
참고 : name = "baby"에 대해 둘 이상의 항목이 반환되면 MultipleObjectsReturned 예외가 발생합니다.
이 방법으로 할 수 있습니다 :
go = Content.objects.filter(name="baby").first()
이제 go 변수는 원하는 객체이거나 None 일 수 있습니다.
참조 : https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.first
일을 쉽게하기 위해 여기에 멋진 답변의 입력을 기반으로 작성한 코드 스 니펫이 있습니다.
class MyManager(models.Manager):
def get_or_none(self, **kwargs):
try:
return self.get(**kwargs)
except ObjectDoesNotExist:
return None
그런 다음 모델에서
class MyModel(models.Model):
objects = MyManager()
그게 다야. 이제 MyModel.objects.get () 및 MyModel.objetcs.get_or_none ()이 있습니다.
exists
필터와 함께 사용할 수 있습니다 .
Content.objects.filter(name="baby").exists()
#returns False or True depending on if there is anything in the QS
존재하는지 알고 싶은 경우에 대한 대안
exists()
과 함께 사용 if
되므로 db에 이중 히트가 발생합니다. 다른 사람에게 도움이 될 수 있도록 의견을 계속 유지합니다.
뷰의 다른 지점에서 예외를 처리하는 것은 정말 번거로울 수 있습니다. models.py 파일에서 사용자 지정 모델 관리자를 정의하는 방법
class ContentManager(model.Manager):
def get_nicely(self, **kwargs):
try:
return self.get(kwargs)
except(KeyError, Content.DoesNotExist):
return None
그런 다음 콘텐츠 모델 클래스에 포함
class Content(model.Model):
...
objects = ContentManager()
이런 식으로 그것은 견해에서 쉽게 다룰 수 있습니다.
post = Content.objects.get_nicely(pk = 1)
if post:
# Do something
else:
# This post doesn't exist
return self.get(**kwargs)
습니다. 대답에 문제가 있다고 말하지 말고, 이후 버전 (또는 다른 것이 나에게 도움이되지 않는 것)으로 사용하려고하는 사람을위한 팁.
사용하는 것이 나쁘지 않다고 생각합니다 get_object_or_404()
from django.shortcuts import get_object_or_404
def my_view(request):
my_object = get_object_or_404(MyModel, pk=1)
이 예는 다음과 같습니다.
from django.http import Http404
def my_view(request):
try:
my_object = MyModel.objects.get(pk=1)
except MyModel.DoesNotExist:
raise Http404("No MyModel matches the given query.")
django 온라인 문서에서 get_object_or_404 () 에 대한 자세한 내용을 읽을 수 있습니다 .
django 1.7부터 다음과 같이 할 수 있습니다.
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):
...
"MyQuerySet.as_manager ()"의 장점은 다음 두 가지가 모두 작동한다는 것입니다.
MyModel.objects.filter(...).get_or_none()
MyModel.objects.get_or_none()
다음 QuerySet
은 모델의 all
객체 queryset 이외의 queryset에서 (예를 들어 부모 인스턴스) :
def get_unique_or_none(model, queryset=None, **kwargs):
"""
Performs the query on the specified `queryset`
(defaulting to the `all` queryset of the `model`'s default manager)
and returns the unique object matching the given
keyword arguments. Returns `None` if no match is found.
Throws a `model.MultipleObjectsReturned` exception
if more than one match is found.
"""
if queryset is None:
queryset = model.objects.all()
try:
return queryset.get(**kwargs)
except model.DoesNotExist:
return None
다음과 같은 두 가지 방법으로 사용할 수 있습니다.
obj = get_unique_or_none(Model, **kwargs)
미리 논의한대로obj = get_unique_or_none(Model, parent.children, **kwargs)
예외없이:
if SomeModel.objects.filter(foo='bar').exists():
x = SomeModel.objects.get(foo='bar')
else:
x = None
예외 사용 :
try:
x = SomeModel.objects.get(foo='bar')
except SomeModel.DoesNotExist:
x = None
파이썬에서 예외를 사용해야 할 때에 대한 약간의 논쟁이 있습니다. 한편으로, "허가보다는 용서를 구하는 것이 더 쉽다". 이에 동의하는 동안 예외는 그대로 유지되어야하며 예외는 "이상적인 경우"가 발생하지 않아야합니다.
로 명명 된 모델에 첨부 된 Django 내장 예외를 사용할 수 있습니다 .DoesNotExist
. 따라서 ObjectDoesNotExist
예외 를 가져올 필요가 없습니다 .
대신에 :
from django.core.exceptions import ObjectDoesNotExist
try:
content = Content.objects.get(name="baby")
except ObjectDoesNotExist:
content = None
우리는 할 수있어:
try:
content = Content.objects.get(name="baby")
except Content.DoesNotExist:
content = None
이것은 메소드가 None을 반환하는 것을 제외하고는 Django의 get_object_or_404에서 복사 한 것입니다. 이는 only()
특정 필드 만 검색 하기 위해 쿼리를 사용해야 할 때 매우 유용 합니다. 이 메소드는 모델 또는 쿼리 세트를 승인 할 수 있습니다.
from django.shortcuts import _get_queryset
def get_object_or_none(klass, *args, **kwargs):
"""
Use get() to return an object, or return None if object
does not exist.
klass may be a Model, Manager, or QuerySet object. All other passed
arguments and keyword arguments are used in the get() query.
Like with QuerySet.get(), MultipleObjectsReturned is raised if more than
one object is found.
"""
queryset = _get_queryset(klass)
if not hasattr(queryset, 'get'):
klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
raise ValueError(
"First argument to get_object_or_none() must be a Model, Manager, "
"or QuerySet, not '%s'." % klass__name
)
try:
return queryset.get(*args, **kwargs)
except queryset.model.DoesNotExist:
return None