수색…


Querysets과 as_manager 메소드를 사용하여 기본 관리자 정의하기

Django manger는 django 모델이 데이터베이스를 쿼리하는 인터페이스입니다. 대부분의 장고 쿼리에서 사용되는 objects 필드는 실제로 django가 생성 한 기본 관리자입니다 (이것은 사용자 정의 관리자를 정의하지 않은 경우에만 생성됩니다).

왜 커스텀 매니저 / 쿼리 세트를 정의할까요?

우리의 코드베이스 전체에 일반적인 쿼리를 작성하지 않고 대신 기억하기 쉬운 추상화를 사용하여 참조하십시오. 예 : 어느 버전이 더 읽기 쉬운 지 스스로 결정하십시오.

  • 모든 활성 사용자 만 가져 오기 : User.objects.filter(is_active=True) vs User.manager.active()
  • 우리 plaform의 모든 활동중인 피부과 전문의를 얻으십시오 : User.objects.filter(is_active=True).filter(is_doctor=True).filter(specialization='Dermatology') vs User.manager.doctors.with_specialization('Dermatology')

또 다른 이점은 내일 모든 psychologistsdermatologists 라고 결정하면 관리자의 쿼리를 쉽게 수정하고 완료 할 수 있다는 것입니다.

다음은 QuerySet 을 작성하고 as_manager 메소드를 사용하여 정의한 사용자 정의 Manager 를 작성하는 예제입니다.

from django.db.models.query import QuerySet

class ProfileQuerySet(QuerySet):
    def doctors(self):
        return self.filter(user_type="Doctor", user__is_active=True)

    def with_specializations(self, specialization):
        return self.filter(specializations=specialization)

    def users(self):
        return self.filter(user_type="Customer", user__is_active=True)

ProfileManager = ProfileQuerySet.as_manager

다음과 같이 모델에 추가합니다.

class Profile(models.Model):
    ...
    manager = ProfileManager()

참고 : 모델에 manager 를 정의한 후에는 모델에 대한 objects 가 더 이상 정의되지 않습니다.

외래 키가있는 모델

우리는 다음 모델들과 함께 작업 할 것입니다 :

from django.db import models

class Book(models.Model):
 name= models.CharField(max_length=50)
 author = models.ForeignKey(Author)

class Author(models.Model):
 name = models.CharField(max_length=50)

우리가 자주 (항상) book.author.name 접근한다고 가정 해보자.

보기에

우리는 매번 다음을 사용할 수 있습니다.

books = Book.objects.select_related('author').all()

그러나 이것은 건조하지 않습니다.

맞춤 관리자

class BookManager(models.Manager):

    def get_queryset(self):
        qs = super().get_queryset()
        return qs.select_related('author')

class Book(models.Model):
    ...
    objects = BookManager()

참고 : 파이썬 2.x에서 super 호출을 변경해야합니다.

이제 뷰에서 사용해야하는 것은

books = Book.objects.all()

템플리트 / 뷰에서 추가 조회가 수행되지 않습니다.

사용자 정의 관리자 정의

종종 published 분야와 같은 것을 가지고있는 모델을 다룰 때가 있습니다. 이러한 종류의 필드는 객체를 검색 할 때 거의 항상 사용되므로 다음과 같이 작성할 수 있습니다.

my_news = News.objects.filter(published=True)

너무 많은 시간. 사용자 정의 관리자를 사용하여 이러한 상황을 처리 할 수 ​​있으므로 다음과 같이 작성할 수 있습니다.

my_news = News.objects.published()

더 좋고 다른 개발자들도 읽기가 쉽습니다.

app 디렉토리에 파일 managers.py 를 만들고 새로운 models.Manager 클래스를 정의하십시오.

from django.db import models


class NewsManager(models.Manager):

    def published(self, **kwargs):
        # the method accepts **kwargs, so that it is possible to filter
        # published news
        # i.e: News.objects.published(insertion_date__gte=datetime.now)
        return self.filter(published=True, **kwargs)

모델 클래스의 objects 속성을 다시 정의하여이 클래스를 사용합니다.

from django.db import models

# import the created manager
from .managers import NewsManager

class News(models.Model):
    """ News model
    """
    insertion_date = models.DateTimeField('insertion date', auto_now_add=True)
    title = models.CharField('title', max_length=255)
    # some other fields here
    published = models.BooleanField('published')

    # assign the manager class to the objects property
    objects = NewsManager()

이제 게시 된 뉴스를 다음과 같이 간단하게 얻을 수 있습니다.

my_news = News.objects.published()

필터링을 더 많이 수행 할 수도 있습니다.

my_news = News.objects.published(title__icontains='meow')


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow