Django에서 빈 쿼리 세트 확인


183

쿼리가 결과를 반환했는지 확인하기 위해 권장되는 관용구는 무엇입니까?
예:

orgs = Organisation.objects.filter(name__iexact = 'Fjuk inc')
# If any results
    # Do this with the results without querying again.
# Else, do something else...

나는 이것을 확인하는 몇 가지 다른 방법이 있다고 생각하지만 숙련 된 장고 사용자가 어떻게 할 것인지 알고 싶습니다. 문서의 대부분의 예제는 아무것도 발견되지 않은 경우를 무시합니다 ...

답변:


205
if not orgs:
    # Do this...
else:
    # Do that...

5
이것은 문서에서도 선호되는 것 같습니다. docs.djangoproject.com/en/1.8/topics/http/shortcuts/#id7
Wtower

1
@Wtower 참조하는 코드는 필터링 표현식이 레코드를 기록하지 않으면 계약이 404를 올리거나 레코드 list가있는 경우 결과 를 생성하도록 합니다. 이 코드는 데이터베이스에 한 번만 도달합니다. 레코드가 리턴되는지 여부를 사용 exist()하거나 count()먼저 확인하는 경우 데이터베이스를 두 번 누르십시오 (한 번 확인하고 한 번은 레코드를 얻음). 이것은 특정한 상황입니다. 그것은에서 그을 수반하지 않는 일반적인 경우 , 쿼리가 레코드를 반환할지 여부를 알 수있는 바람직한 방법은 사용 할 것입니다if queryset:...
루이

1
@Louis 내가 참조하는 코드 if not my_objects:는 문서 에서이 작업을 수행하는 방법을 보여주는 줄 이 들어있는 예제 일뿐 입니다. 다른 모든 것은 전혀 관련이 없으므로 귀하의 요점을 알 수 없습니다. 그들은 천 번의 쿼리를 할 수 있었고 이것이이 답변의 요점이 아니기 때문에 여전히 관련이 없을 것입니다.
Wtower

1
@Wtower 이것은 어떻게 작동 하는지에 대한 설명 일 뿐이며 쿼리 셋에 요소가 있는지 확인하는 기본 방법은 아닙니다 . 쿼리 세트에서 list ()를 수행하면 쿼리 세트의 모든 객체를 가져 오며, 많은 행이 반환되면 두 번 쿼리하는 것보다 나쁩니다. get_object_or_404
minmaxavg 2016

1
더 자세한 답변은 아래 @ leonid-shvechikov의 답변을 참조 .exists()하십시오 .qs를 평가하지 않을 경우 사용하는 것이 더 효율적입니다.
guival

191

1.2 버전부터 Django에는 QuerySet이 있습니다. 가장 효율적인 존재 () 메소드 :

if orgs.exists():
    # Do this...
else:
    # Do that...

그러나 QuerySet을 평가하려는 경우 다음을 사용하는 것이 좋습니다.

if orgs:
   ...

자세한 내용 은 QuerySet.exists () documentation 를 참조하십시오 .


.exists ()는 .filter () 전용이며 .get ()에 대한 것이 있습니까?

.get쿼리 셋을 반환하지 않습니다. 객체를 반환합니다. 그래서 구글을 위해
04 분

당신이 큰 검색어 세트있는 경우에 눈에 띄게에만 더 효율적입니다 : docs.djangoproject.com/en/2.1/ref/models/querysets/#exists을
나단 존스

16

많은 수의 객체가있는 경우 (때로는) 훨씬 빠를 수 있습니다.

try:
    orgs[0]
    # If you get here, it exists...
except IndexError:
    # Doesn't exist!

거대한 데이터베이스로 작업하고있는 프로젝트에서 not orgs400 + ms이며 orgs.count()250ms입니다. 가장 일반적인 사용 사례 (결과가있는 경우) 에서이 기술은 종종 20ms 미만으로 떨어집니다. (내가 찾은 한 사례는 6이었습니다.)

물론 데이터베이스가 결과를 찾는 데 얼마나 멀리 있는지에 따라 훨씬 길어질 수 있습니다. 또는 더 빨리 찾으면 더 빠릅니다. YMMV.

편집 : 이것은 것입니다 종종 느린보다 orgs.count()결과가 발견되지 않는 경우가 필터링하고있는 조건이 희귀 한 특히 경우; 결과적으로 뷰가 존재하는지 확인하거나 Http404를 발생시켜야하는 뷰 함수에 특히 유용합니다. 사람들은 희망하는 곳에서 더 자주 존재하는 URL을 요구하고 있습니다.


10

쿼리 집합의 공허함을 확인하려면

if orgs.exists():
    # Do something

또는 쿼리 세트에서 첫 번째 항목을 확인할 수 있습니다. 존재하지 않는 경우 다음을 반환합니다 None.

if orgs.first():
    # Do something

7
if orgs.exists()약 5 년 전에 제공된 답변 으로 덮여있었습니다 . 이 답변이 테이블에 가져 오는 유일한 것은 아마도 새로운 것입니다 if orgs.first(). (심지어이 논쟁의 여지가있다 : 그것은 일을 실질적으로 다른 orgs[0] 제안 전에 너무 오년에 대해?) 당신은 해답의 일부를 개발한다고 하나는이 작업을 수행 할 것입니다 때 대신 이전에 제안 된 다른 솔루션?
루이

9

가장 효율적인 방법 (django 1.2 이전)은 다음과 같습니다.

if orgs.count() == 0:
    # no results
else:
    # alrigh! let's continue...

5
.exists ()가 훨씬 더 효율적인 것 같습니다
dzida

5
.exists ()는 내 의견 몇 달 후 추가되었으며 Django 1.2 (해당 API 포함)는 ~ 8 개월 후에 릴리스되었습니다. 그러나 투표를하지 않은 사실에 감사하고 사실을 확인하지 않아도됩니다.
Bartosz

4
죄송합니다.보다 정확한 답변을 위해 귀하의 답변에 작은 편집을 추가했습니다.
dzida

4

나는 술어에 동의하지 않는다

if not orgs:

그것은해야한다

if not orgs.count():

상당히 큰 결과 세트 (~ 150k 결과)와 동일한 문제가 발생했습니다. 연산자는 QuerySet에서 오버로드되지 않으므로 결과는 실제로 확인하기 전에 목록으로 압축 해제됩니다. 필자의 경우 실행 시간이 3 회 줄었습니다.


6
__nonzero__는 이미 QuerySet에 과부하되어 있습니다. 결과가 캐시되지 않은 경우 (처음 쿼리 세트를 사용하지 않는 경우) __nonzero__의 동작은 쿼리 세트의 모든 요소를 ​​반복하는 것입니다. 세트가 크면 매우 나쁩니다.
hedleyroos

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.