На какие функции влияет порядок менеджеров Django? - PullRequest
1 голос
/ 26 июля 2011

Итак, я прочитал большинство документов и немного искал по SO, но не могу найти ответ на свой вопрос.Я начну с кода.

# Manager
class ActiveManager(models.Manager):
    def get_query_set(self):
        return super(ActiveManager, self).get_query_set().filter(is_active=True)
# Model
class ModelA(models.Model):
    # ...
    is_active = models.BooleanField()
    objects = ActiveManager()
    all_objects = models.Manager()

Итак, пока я играл, я заметил, что если бы я написал это таким образом и использовал get_object_or_404(), то он использовал бы ActiveManagerсначала найти все активные записи, а затем вернуть ту, которая относится к моему запросу.Однако, если я сменил порядок менеджеров:

class ModelA(models.Model):
    # ...
    all_objects = models.Manager()
    objects = ActiveManager()

Тогда он использует менеджер по умолчанию, в данном случае all_objects, для выполнения запроса.Мне интересно, какие другие функции влияют на это изменение.

РЕДАКТИРОВАТЬ: я понимаю, что первый менеджер в классе становится менеджером по умолчанию, но мне интересно, какие конкретные функции используют этот менеджер по умолчанию (например, get_object_or_404)

Ответы [ 2 ]

2 голосов
/ 26 июля 2011

Вот соответствующий бит из документов: "Если вы используете пользовательские Manager объекты, обратите внимание, что первые Manager Django-встречи (в порядке, в котором они определены в модели) имеют особый статус. Django интерпретирует первый Manager, определенный в классе, как «значение по умолчанию» Manager, и несколько частей Django (включая dumpdata) будут использовать это Manager исключительно для этой модели. Хорошая идея - быть осторожным при выборе менеджера по умолчанию, чтобы избежать ситуации, когда переопределение get_query_set() приводит к невозможности получить объекты, с которыми вы хотели бы работать ".

Если вы посмотрите на способ реализации get_object_or_404 , они используют атрибут _default_manager модели, который Django ссылается на первого встреченного менеджера. (Насколько я знаю, все внутренние компоненты Django работают таким образом - они никогда не используют Model.objects и т. Д., Потому что не следует полагать, что менеджер по умолчанию называется objects).

0 голосов
/ 26 июля 2011

Это влияет на многие вещи. Имя по умолчанию для менеджера, objects, просто по умолчанию, но не обязательно. Если вы не включили objects в определение модели и просто определили менеджера как all_objects, ModelA.objects не будет существовать. Django просто назначает менеджера по умолчанию, если в модели нет других менеджеров, и вы сами не определили objects.

В любом случае, из-за этого Django берет первого менеджера, определенного в модели, и вызывает, что «по умолчанию», а затем использует менеджера «по умолчанию», когда ему необходимо обратиться к менеджеру модели (потому что, опять же, он не может просто используйте objects, потому что objects не может быть определен).

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

...