[python] django의 쿼리 세트에서 첫 번째 객체를 얻는 가장 빠른 방법은 무엇입니까?

종종 장고의 쿼리 세트에서 첫 번째 객체를 가져 오거나 반환하려고합니다. None 없는 경우 합니다. 이 작업을 수행하는 모든 방법이 많이 있습니다. 그러나 어느 것이 가장 성능이 좋은지 궁금합니다.

qs = MyModel.objects.filter(blah = blah)
if qs.count() > 0:
    return qs[0]
else:
    return None

이로 인해 두 번의 데이터베이스 호출이 발생합니까? 낭비 인 것 같습니다. 이게 더 빠릅니까?

qs = MyModel.objects.filter(blah = blah)
if len(qs) > 0:
    return qs[0]
else:
    return None

다른 옵션은 다음과 같습니다.

qs = MyModel.objects.filter(blah = blah)
try:
    return qs[0]
except IndexError:
    return None

이렇게하면 단일 데이터베이스 호출이 생성됩니다. 그러나 예외 객체를 생성하는 데는 많은 시간이 필요합니다. 이는 실제로 필요한 모든 것이 사소한 if-test 일 때 메모리를 많이 사용하는 작업입니다.

단 하나의 데이터베이스 호출로 예외 개체와 함께 메모리를 제거하지 않고 어떻게 할 수 있습니까?



답변

(2013 11월 해제) 장고 1.6 도입 편의 방법 first()last()어떤 생성 된 예외 복귀 삼키는 None의 검색어가 더 객체를 반환하지 않는 경우.


답변

정답은

Entry.objects.all()[:1].get()

사용할 수있는 것 :

Entry.objects.filter()[:1].get()

먼저 모든 레코드의 전체 데이터베이스 호출을 강제로 수행하므로 목록으로 전환하지 않으려 고합니다. 위의 작업을 수행하면 첫 번째 만 가져옵니다. 당신은 심지어 사용할 수 있습니다.order_by 당신이 원하는 첫 번째를 얻을 수 있도록 수 있습니다.

.get()객체 를 추가 하지 않고 QuerySet을 다시 가져 오십시오.


답변

r = list(qs[:1])
if r:
  return r[0]
return None


답변

이제 Django 1.9에는 first() 쿼리 세트에 대한 메소드가 있습니다.

YourModel.objects.all().first()

이것은 queryset이 ​​비어 있으면 예외를 throw하지 않는 것보다 낫 .get()거나 더 나은 방법 [0]입니다. 따라서, 당신은 사용을 확인할 필요가 없습니다.exists()


답변

첫 번째 요소를 자주 얻으려면 다음과 같이 QuerySet을 확장하십시오.

class FirstQuerySet(models.query.QuerySet):
    def first(self):
        return self[0]


class ManagerWithFirstQuery(models.Manager):
    def get_query_set(self):
        return FirstQuerySet(self.model)

다음과 같이 모델을 정의하십시오.

class MyModel(models.Model):
    objects = ManagerWithFirstQuery()

그리고 이것을 다음과 같이 사용하십시오 :

 first_object = MyModel.objects.filter(x=100).first()


답변

이것은 잘 작동 할 수 있습니다 :

def get_first_element(MyModel):
    my_query = MyModel.objects.all()
    return my_query[:1]

비어 있으면 빈 목록을 반환하고, 그렇지 않으면 목록 내의 첫 번째 요소를 반환합니다.


답변

이렇게 될 수 있습니다

obj = model.objects.filter(id=emp_id)[0]

또는

obj = model.objects.latest('id')