SW개발/Django

[Django]get_object() 란?

get_object() 란?

간단하게 get_object()는 pk로 queryset을 필터링 하고, queryset 결과에서 object를 뽑아서 return 시켜주는 함수이다.

실제 코드는 class SingleObjectMixin(ContentMixin) 내에서 확인할 수 있다.

 

https://docs.djangoproject.com/en/3.2/ref/class-based-views/mixins-single-object/#singleobjectmixin

 

Single object mixins | Django documentation | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

 

내부의 주석을 번역하면서 하나씩 살펴보기로 하자.

def get_object(self, queryset=None):
    """
    view가 display 하고있는 object를 반환합니다.

    URLconf에 `self.queryset` 과 `pk` 혹은 `slug` 인수가 필요합니다.
    서브클래스는 이를 오버라이딩하여 object를 반환할 수 있습니다.
    """
    # 제공된 경우, custom queryset을 사용합니다. 이것은 서브클래스를 위해 필요합니다.
    # like DateDetailView
    if queryset is None:
        queryset = self.get_queryset()

    # 다음으로, pk로 검색을 시도한다.
    pk = self.kwargs.get(self.pk_url_kwarg)
    slug = self.kwargs.get(self.slug_url_kwarg)
    if pk is not None:
        queryset = queryset.filter(pk=pk)
        
    # 다음으로, slug로 검색을 시도한다.
    if slug is not None and (pk is None or self.query_pk_and_slug):
        slug_field = self.get_slug_field()
        queryset = queryset.filter(**{slug_field: slug})

    # 이들 중 어느것도 정의되지 않는다면, 에러를 발생시킨다.
    if pk is None and slug is None:
        raise AttributeError(
            "Generic detail view %s must be called with either an object "
            "pk or a slug in the URLconf." % self.__class__.__name__
        )

    try:
        # 이제 필터링 된 queryset에서 object를 가져온다.
        obj = queryset.get()
    except queryset.model.DoesNotExist:
        raise Http404(_("No %(verbose_name)s found matching the query") %
                      {'verbose_name': queryset.model._meta.verbose_name})
    return obj

우선 함수의 파라미터(인자)를 살펴보면 queryset을 받게 되어있다. 즉, queryset을 함수 호출시에 인수로 보내면 custom queryset을 이용할 수 있다. 인자를 받지 않을 경우 해당 object의 기본 queryset을 참조하게 되어있다.

 

다음으로, pk를 통해서 queryset을 filter 하게 된다. 이 또한 없을 경우에는 slug를 통해 filter를 시도하게 된다.

만약 이들 중 어느것도 정의되지 않았다면 AttributeError를 발생시키게 된다.

 

마지막으로, queryset에서 object를 .get()을 통해 추출하고 return 하면서 함수를 종료한다.

즉, pk 및 slug 필드로 object를 가져올 때 이용되는 함수이다.


하나의 의문점

앞서 얘기 했던 것과 거의 동일한 기능을 하는 코드가 존재한다. 

'''
Leffe라는 클래스내라고 가정.
'''
# get_object() 이용
leffe = self.get_object()

# 기본 ORM 이용
leffe = Leffe.objects.get(pk=pk)

위의 두 코드는 같은 기능을 하는 코드이다. 구현하는 방식의 차이만 있을 뿐이다. 보통 get_object()의 경우 self.~~로 사용하는 경우가 많기에 self 와 찾고자 하는 class가 일치한다면 get_object()를 쓰고, 그 외의 경우라면 objects.get()을 쓰는 것이 좋다고 생각한다.

 

self를 잘 이용하는 것이 조금 더 객체지향스럽고, pythonic한 코드이지 않을까 한다.

 

공부하면서 정리한 내용이니 틀릴 수 있습니다. 댓글로 남겨주시면 감사하겠습니다.

 

728x90