Table of Contents
class Manager #
Manager는 데이터베이스 질의 작업이 Django 모델에 제공되는 인터페이스입니다.
Django 응용프로그램의 모든 모델에 대해 하나 이상의 Manager가 있습니다. 관리자 클래스의 작동 방법은 질의 작성에 설명되어 있습니다.
Manager names #
기본적으로 Django는 모든 Django 모델 클래스에 개체 이름을 가진 Manager를 추가합니다. 그러나 필드 이름으로 개체를 사용하거나 Manager에 대해 개체 이외의 이름을 사용하려는 경우 모델별로 이름을 변경할 수 있습니다.
지정된 클래스의 관리자 이름을 변경하려면 유형 모델의 클래스 특성을 정의합니다.
해당 모델의 Manager()입니다.
from django.db import models
class Person(models.Model):
#...
people = models.Manager()
이 예제 모델을 사용하면 Person.objects는 AttributeError 예외를 생성하지만, Person.people.all()은 Person objects의 전체 리스트를 제공합니다.
Custom managers #
기본 Manager 클래스를 확장하고 모델에서 사용자 정의 Manager를 인스턴스화하여 특정 모델에서 사용자 정의 Manager를 사용할 수 있습니다.
Manager를 사용자 정의하는 데는 두 가지 이유가 있습니다.
즉, 추가 Manager 메서드를 추가하거나 Manager가 반환하는 초기 QuerySet을 수정해야 합니다.
Adding extra manager methods #
추가 Manager 메서드를 추가하는 것이 "table-level" 기능을 모델에 추가하는데 선호되는 방법입니다.
예를 들어 이 사용자 지정 Manager는 with_counts() 메서드를 추가합니다.
from django.db import models
from django.db.models.functions import Coalesce
class PollManager(models.Manager):
def with_counts(self):
return self.annotate(
num_responses=Coalesce(models.Count("response"), 0)
)
class OpinionPoll(models.Model):
question = models.CharField(max_length=200)
objects = PollManager()
class Response(models.Model):
poll = models.ForeignKey(OpinionPoll, on_delete=models.CASCADE)
# ...
이 예에서는 OpinionPoll.objects.with_counts()를 사용하여 num_responses 속성이 첨부된 OpinionPoll 개체의 QuerySet을 가져옵니다.
사용자 정의 Manager 메서드는 사용자가 원하는 모든 것을 반환할 수 있습니다.
꼭 QuerySet을 반환할 필요는 없습니다.
또 다른 주의 사항은 Manager 메서드가 self.model에 액세스하여 연결된 모델 클래스를 가져올 수 있다는 것입니다.
Modifying a manager’s initial QuerySet #
Manager의 기본 QuerySet은 시스템의 모든 개체를 반환합니다.
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
...Book.objects.all() 은 데이터베이스의 모든 책을 반환합니다.
Manager.get_queryset() 메서드를 재정의하여 Manager의 기본 QuerySet을 재정의할 수 있습니다.
get_queryset()은 필요한 속성이 있는 QuerySet을 반환해야 합니다.
예를 들어, 다음 모델에는 두 개의 Manager가 있습니다.
하나는 모든 개체를 반환하고 다른 하나는 Roald Dahl의 책만 반환하는 것입니다.
# First, define the Manager subclass.
class DahlBookManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(author='Roald Dahl')
# Then hook it into the Book model explicitly.
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
objects = models.Manager() # The default manager.
dahl_objects = DahlBookManager() # The Dahl-specific manager.
이 샘플 모델을 사용하면 Book.objects.all()은 데이터베이스의 모든 책을 반환하지만, Book.dahl_objects.all()은 Roald Dahl이 작성한 책만 반환합니다.
get_queryset()은 QuerySet 객체를 반환하므로 filter()와 exclude() 및 기타 모든 QuerySet 메서드를 사용할 수 있습니다.
Book.dahl_objects.all()
Book.dahl_objects.filter(title='Matilda')
Book.dahl_objects.count()
모델에 원하는 만큼 Manager() 인스턴스를 연결할 수 있습니다.
이 방법은 모델에 대한 일반적인 "filter"를 정의하는 반복을 줄이는 방법입니다.
예를 들어,
class AuthorManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(role='A')
class EditorManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(role='E')
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
role = models.CharField(max_length=1, choices=[('A', _('Author')), ('E', _('Editor'))])
people = models.Manager()
authors = AuthorManager()
editors = EditorManager()
이 예시에서, Person.authors.all(), Person.editors.all(), Person.people.all()를 요청하여 예측할 수 있는 결과를 얻을 수 있습니다.
출처 - djangoproject-4.1-managers