Как Django узнает, какой менеджер моделей использовать?

Поэтому мне интересно использовать приведенный ниже пример кода в проекте Django, но я озадачен, пытаясь понять, как я мог бы явно вызвать один менеджер моделей.

class AuthorManager(models.Manager):
    def get_queryset(self):
        return super(AuthorManager,    self).get_queryset().filter(role='A')

class EditorManager(models.Manager):
    def get_queryset(self):
        return super(EditorManager, self).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 Joshua Blevins    schedule 11.06.2017    source источник


Ответы (2)


В соответствии с документацией, вы можете вызвать менеджера любой модели из своего просмотры с Person.authors.get_queryset или Person.editor.get_queryset. Кроме того, вы можете передавать данные обратно любому менеджеру. Например:

В представлениях:

data = {
    'first_name' : request.POST['first_name'],
    'last_name' :request.POST['last_name'],
    'email' : request.POST['email'],
  }
author = Person.authors.new_author(data)
editor = Person.editor.new_editor(data)

Переменная "автор"/"редактор" выше станет тем, что ваши модели передают обратно.

Очевидно, вы хотели бы определить новые методы в своих менеджерах. Например.

В моделях:

class AuthorManager(models.Manager):
    def new_author(self):
        Person.authors.create(...)

class EditorManager(models.Manager):
    def new_editor(self):
        Person.editors.create(...)

Вы можете выбрать, чтобы ваши модели передавали любую информацию о пользователе, которая вам нужна, в ваши представления.

person Jake Kieranan    schedule 11.06.2017
comment
Итак, в моем PersonViewSet я могу вызвать Person.authors.filter(name='eric') или что-то в этом роде? Это главный недостаток, с которым я столкнулся, чтобы по-настоящему использовать это. - person Joshua Blevins; 12.06.2017
comment
Да, конечно, вы можете сделать простой вызов базы данных в представлениях, но для более сложной логики, такой как проверки и т. д., вы хотите отправить это обратно в модели. - person Jake Kieranan; 12.06.2017
comment
И любая работа, которую вы можете вернуть в модели, имеет ручку Manger, например. создать пользователя с валидацией. Лучше распределить как можно больше логики по моделям (и вне представлений). - person Jake Kieranan; 12.06.2017
comment
Можете ли вы привести простой пример того, как я могу отправить эту логику обратно в модели, а затем вызвать их из представлений? Я думал, что единственной целью представлений было принять запрос и дать ответ. Но это включает в себя представление, выполняющее логику. Я хотел бы, чтобы ваш способ был реализован. - person Joshua Blevins; 14.06.2017
comment
Как правило, вам нужны худые контроллеры и толстые модели. Таким образом, если у вас есть форма на вашем сайте и вы хотите убедиться, что каждое поле имеет значение (определенное количество символов или регулярное выражение электронной почты) до того, как оно будет отправлено в вашу базу данных, вам нужно будет выполнить проверки. Это может занять много строк кода, поэтому вы помещаете проверки в свой менеджер моделей, а затем, например, заставляете менеджера отправлять сообщения об ошибках обратно в ваше представление, если проверки не были выполнены. Это ясно? - person Jake Kieranan; 14.06.2017
comment
это имеет смысл. можете ли вы показать мне, как это будет реализовано? - person Joshua Blevins; 14.06.2017

class PersonQuerySet(models.QuerySet):
    def authors(self):
        return self.filter(role='A')

    def editors(self):
        return self.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()
        objects = PersonQuerySet.as_manager()

Найти авторов и редакторов:

authors = Person.objects.authors()
editors = Person.objects.editors()
person Neeraj Kumar    schedule 11.06.2017