Цель использования пользовательского менеджера для создания объектов с помощью django?

Я вижу в документации Django:

Справочник по экземпляру модели: создание объектов< /сильный>

У вас может возникнуть соблазн настроить модель, переопределив метод __init__. Однако в этом случае постарайтесь не изменять сигнатуру вызова, так как любое изменение может помешать сохранению экземпляра модели.
Вместо переопределения __init__ попробуйте использовать один из следующих подходов:

  • Добавьте метод класса в класс модели.
  • Добавьте метод в пользовательский менеджер (обычно предпочтительнее)

Почему второе решение «обычно предпочтительнее»?

В ситуации, когда у меня есть модель B, которая расширяет модель A через отношение OneToOne, и я хочу создать метод, генерирующий объект B, который также генерирует соответствующий объект A, как «лучше» использовать пользовательский менеджер как было предложено, учитывая, что я, вероятно, не буду использовать этот менеджер ни для чего, кроме того, что предоставляется менеджером по умолчанию?


person Levans    schedule 08.08.2013    source источник


Ответы (1)


Я думаю, что это предпочтительнее, потому что код выглядит чище. Вы также можете слишком много вчитываться в акценты, поскольку польза или разница не так уж велики. Тем не менее, при реализации вещей я использую предложенный подход.

Рассмотрим следующую модель (исключительно в иллюстративных целях):

class Vehicle(models.Model):
    wheels = models.IntegerField()
    color = models.CharField(max_length=100)

В вашем приложении часто возникает необходимость получить все автомобили, или все мотоциклы, или любой другой тип транспортного средства. Чтобы все было СУХИМ, вам нужна стандартная форма получения этих данных. Используя методы класса, вы получите следующее:

class Vehicle(models.Model):
    #(...)
    @classmethod
    def cars(cls):
        return Vehicle.objects.filter(wheels=4)

cars = Vehicle.cars()
green_cars = Vehicle.cars().filter(color='green')

Если вы создадите менеджера, вы получите что-то вроде этого:

class CarManager(models.Manager):
    def get_query_set(self):
        return super(CarManager, self).get_query_set().filter(wheels=4)

class Vehicle(models.Model):
    #(...)
    car_objects = CarManager()

cars = Vehicle.car_objects.all()
green_cars = Vehicle.car_objects.filter(color='green')

На мой взгляд, последний выглядит чище, особенно когда все становится сложнее. Это избавляет вас от беспорядка в определениях вашей модели и сохраняет вещи, аналогичные использованию менеджера objects по умолчанию.

person jro    schedule 08.08.2013
comment
На мой взгляд, это в основном потому, что Django интегрирует свой ORM с множеством других пакетов и библиотек, таких как, например, DRF. Этот тип пакетов используется для интеграции с моделями и вызова Model.objects в обычных условиях. Реализовать методы на моделях, на мой взгляд, наивное решение. Это очевидно просто и понятно, но как поступить, когда нужно получить например категорию зеленых автомобилей? Другой метод! - person Yago Gehres; 12.09.2020