Мне было интересно, удалось ли (и если да, как) объединить несколько менеджеров для создания набора запросов, на который влияют оба отдельных менеджера. Я объясню конкретный пример, над которым я работаю:Django Manager Chaining
У меня есть несколько классов абстрактных моделей, которые я использую, чтобы обеспечить небольшую специфическую функциональность для других моделей. Две из этих моделей - это DeleteMixin и GlobalMixin.
DeleteMixin определяется как, например:
class DeleteMixin(models.Model):
deleted = models.BooleanField(default=False)
objects = DeleteManager()
class Meta:
abstract = True
def delete(self):
self.deleted = True
self.save()
В основном это обеспечивает псевдо-удаление (удаленный флаг) вместо того, чтобы на самом деле удаления объекта.
GlobalMixin определяется как таковую:
class GlobalMixin(models.Model):
is_global = models.BooleanField(default=True)
objects = GlobalManager()
class Meta:
abstract = True
Это позволяет любому объекту быть определен либо как глобальный объект или частный объект (например, как открытый/закрытый пост блога).
У обоих из них есть свои менеджеры, которые влияют на возвращаемый запрос. Мой DeleteManager фильтрует запрос, чтобы возвращать результаты только с установленным флажком False, в то время как GlobalManager фильтрует запрос, чтобы возвращать результаты, отмеченные как глобальные. Вот декларация как:
class DeleteManager(models.Manager):
def get_query_set(self):
return super(DeleteManager, self).get_query_set().filter(deleted=False)
class GlobalManager(models.Manager):
def globals(self):
return self.get_query_set().filter(is_global=1)
Желаемая функциональность будет иметь модель расширения оба этих абстрактные модели и предоставить возможность возвращать только те результаты, которые являются и не удаленными и глобальными. Я проверил тестовый пример на модели с 4 экземплярами: один был глобальным и не удалялся, один был глобальным и удалялся, один был неглобальным и не удалялся, а один был неглобальным и удалялся. Если я попытаюсь получить набор результатов как таковой: SomeModel.objects.all(), я получаю экземпляр 1 и 3 (два не удаленных - отлично!). Если я попробую SomeModel.objects.globals(), я получаю сообщение об ошибке, которое DeleteManager не имеет глобальных переменных (это предполагает, что мое объявление модели таково: SomeModel (DeleteMixin, GlobalMixin). Если я отменил порядок, t получить ошибку, но она не отфильтровывает удаленные). Если я изменю GlobalMixin, чтобы привязать GlobalManager к глобальным переменным вместо объектов (поэтому новой командой будет SomeModel.globals.globals()), я получаю экземпляры 1 и 2 (два глобальных символа), в то время как мой предполагаемый результат будет состоять только в том, чтобы получить экземпляр 1 (глобальный, не удаленный).
Я не был уверен, что кто-то столкнулся с ситуацией, подобной этому, и пришел к результату. Либо способ заставить его работать в моем текущем мышлении, либо переработать, который обеспечивает функциональность, с которой я буду, очень ценится. Я знаю, что этот пост был немного длинным. Если потребуется больше объяснений, я был бы рад предоставить его.
Edit:
Я отправил окончательное решение, я использовал для этой конкретной проблемы ниже. Он основан на ссылке на пользовательский QuerySetManager Саймона.
Это, кажется, сделали свое дело. Я должен был больше сосредоточиться на наборе запросов и меньше на менеджере. Я отправил свое возможное решение в качестве ответа, хотя я выбрал ваш, как лучший. – Adam