404를 반환하지 않고 django 뷰에 객체가 있는지 확인하는 올바른 방법은 무엇입니까?


93

개체가 있는지 확인하고 개체를 반환 한 다음 해당 작업을 수행합니다. 404를 반환하지 않고 수행하는 올바른 방법은 무엇입니까?

try:
    listing = RealEstateListing.objects.get(slug_url = slug)
except:
    listing = None

if listing:

Rasiel, 다른 대답을 받아들이는 것이 좋습니다. 이 작업을 수행하는 올바른 방법 인 것으로 보이며 허용 된 답변보다 훨씬 더 많이 찬성되었습니다.
Azendale 2015

1
나는 그것을 고려할 수 있지만, 2010 년 5 월 17 일에 출시 된 Django 1.2에서 소개되었습니다. 내 질문이 09 년에 제출 된 것을 눈치 채 셨다면 ... 이것은 당시 정답이었습니다. Exists ()가 이제 가장 좋은 방법으로 간주된다면 두 번째 대답을 선택하는 것이 의미 론적으로 정확할 것이라고 생각합니다.
Rasiel

Rasiel, 그 당시 정답이었던 것이 말이됩니다. 그러나 stackoverflow 사이트는 사이트가 사람들의 문제에 대한 해결책을 찾는 것처럼 최상의 답변으로 좋은 / 공식적인 질문을 구축하는 것만큼이나 중요합니다. 따라서 현재 "공식적으로 올바른"대답을 선택하라는 제 제안입니다.
Azendale 2015

if listing:을해야한다 else:.
Chronial

답변:


117

404가 주어지지 않으면 404 래퍼를 사용하지 않을 것입니다. 그것은 의도의 오용입니다. 대신 DoesNotExist를 잡으십시오.

try:
    listing = RealEstateListing.objects.get(slug_url=slug)
except RealEstateListing.DoesNotExist:
    listing = None

+1 : 당신이 404하지 않으려면 예,이는 허용 하나보다 더 나은 솔루션입니다
칼 마이어

Yap, 이것이 더 나은 해결책 인 것 같습니다
Rasiel

3
이 솔루션은 exists()개체로 무언가를해야하는 경우 보다 더 잘 작동 합니다.
SaeX

2
추가하고 싶습니다 values_list('id', flat=True). 내가 존재하는 경우 단지 볼 필요가있는 경우listing = RealEstateListing.objects.values_list('id', flat=True).get(slug_url=slug)
erajuan

이 구문에서 이상한 점 RealEstateListing.DoesNotExist은 객체 자체가 아니라 모델을 참조한다는 것입니다. 왜 그렇지 RealEstateListing.objects.get(slug_url=slug).DoesNotExist않습니까?
Maxim Vallee

199

다음을 수행 할 수도 있습니다.

if not RealEstateListing.objects.filter(slug_url=slug).exists():
    # do stuff...

때로는 try: except:블록 을 사용하는 것이 더 명확하고 한 줄로 exists()코드를 더 명확하게 보이게하는 경우도 있습니다. 모두 애플리케이션 논리에 따라 다릅니다.



7
이것은 좋은 방법이며 대답해야한다
Jharwood

3
나는 그것이에서 exists()작동하지 않는다고 가정하고 get()있습니다.
Eduard Luca

9
이 솔루션은 해당 개체를 사용하지 않을 경우에만 유효합니다. 그렇지 않으면 (OPs 상황에서와 같이) 잘못된 것이며 허용 된 솔루션보다 훨씬 느립니다. get()나중에 수행 하면 데이터베이스에 두 번째 쿼리를 보냅니다.
Chronial

1
당신은 객체 뭔가를 (있는 경우) 할 수있는 존재를 확인하는 경우, 내가 선호하는 것 try-except이상 exists().
Jithin Pavithran

7
listing = RealEstateListing.objects.filter(slug_url=slug).first() 

2
이것은 하나의 할당 만 필요하고 try / except 블록을 사용할 필요가 없기 때문에 나중에 잠재적 인 개체를 사용해야하는 경우 가장 좋은 솔루션입니다. 나중에 간단히 존재 여부를 테스트 할 수 있습니다.if listing:
Michael Hays 2011

try / except를 피하는 것은 나쁜 습관입니다. 소프트웨어 개발의 가장 중요한 측면 중 하나는 예외를 제어 할 수 있다는 것입니다. 이는 좋은 사용자 경험을 제공 할 수 있습니다. 무언가가 제대로 작동하지 않을 때 사람들에게 알립니다. 둘째; QuerySet의 존재를 테스트하려면 .exists ()를 사용하십시오. 그렇지 않으면 객체입니다. 기본 키로 존재 여부 테스트 .... if object.pk : // run code ()이 쿼리는 객체의 모든 데이터를 검색하는 것보다 훨씬 빠릅니다. 존재하는지 알고 싶을뿐입니다.
Wolfgang Leon

2
try / except 및을 사용하는 솔루션이 이미 있습니다 .exists(). 나는 일을하는 방법에 대해 여러 가지 다른 답변을 갖는 것이 좋은 생각이라고 생각합니다. 객체가 존재하는 경우에도 사용하려는 사람들에게이 방법이 더 좋습니다. 나는 시도 / 예외를 피해야하는지 여부에 관계없이 어떤 규칙도 만들지 않을 것입니다. 예를 들어 매우 간결한 코드를 만들고 싶은 경우에는 때로는 좋지만 때로는 좋지 않습니다.
Henrik Heino

0

다음과 같이 간단하게 할 것입니다.

listing = RealEstateListing.objects.filter(slug_url=slug)
if listing:
    # do stuff

try / catch가 필요하지 않습니다. 결과에 잠재적으로 여러 객체가있는 경우 사용자 Henrik Heino가 표시 한 것처럼 first ()를 사용하십시오.


쿼리 세트에서 .first ()를 수행하거나 조건부에서 .first ()를 수행하지 않는 한 항상 True를 반환합니다.
B.Adler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.