Django                
            Пользовательские менеджеры и запросы
        
        
            
    Поиск…
Определение базового менеджера с использованием Querysets и метода `as_manager`
 Django manger - это интерфейс, через который модель django запрашивает базу данных. Поле objects используемое в большинстве запросов django, фактически является менеджером по умолчанию, созданным для нас django (это создается только в том случае, если мы не определяем настраиваемых менеджеров). 
Почему мы должны определить пользовательский менеджер / набор запросов?
Чтобы избежать написания общих запросов по всей нашей базе кода и вместо этого ссылаться на них, используя более легкую для запоминания абстракцию. Пример. Определите, какая версия более читаема:
-  Только получить всех активных пользователей: User.objects.filter(is_active=True)vsUser.manager.active()
-  Получить всех активных дерматологов на нашей платформе: User.objects.filter(is_active=True).filter(is_doctor=True).filter(specialization='Dermatology')vsUser.manager.doctors.with_specialization('Dermatology')
 Еще одно преимущество заключается в том, что если завтра мы решаем, что все psychologists также являются dermatologists , мы можем легко изменить запрос в нашем Менеджере и сделать с ним. 
 Ниже приведен пример создания настраиваемого Manager определяется путем создания QuerySet и использования метода as_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 больше не будут определены для модели. 
select_related для всех запросов
Модель с ForeignKey
Мы будем работать с этими моделями:
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 доступ к 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()
 Примечание : вызов super должен быть изменен для python 2.x 
Теперь все, что нам нужно использовать в представлениях
books = Book.objects.all()
и никаких дополнительных запросов в шаблоне / представлении не будет.
Определение пользовательских менеджеров
 Очень часто приходится иметь дело с моделями, которые имеют что-то вроде published области. Такие типы полей почти всегда используются при извлечении объектов, так что вы обнаружите, что пишете что-то вроде: 
my_news = News.objects.filter(published=True)
слишком много раз. Вы можете использовать пользовательских менеджеров для решения этих ситуаций, чтобы затем вы могли написать что-то вроде:
my_news = News.objects.published()
который является более приятным и легким для чтения другими разработчиками.
 Создайте файл 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')