#python #django
#python #django
Вопрос:
Предположим, у меня есть модель:
class Car(models.Model):
name = models.CharField(max_length=50)
is_active = models.BooleanField(default=True)
Когда я запрашиваю Car, я всегда хочу возвращать объекты, удовлетворяющие is_active=True .
Для этого, выполняя поиск в StackOverflow, я понимаю, что лучше всего использовать ModelManager, например:
class CarManager(models.ModelManager):
def get_queryset(self):
return super().get_queryset().filter(is_active=True)
И используйте этот менеджер в моей модели.
class Car(models.Model):
name = models.CharField(max_length=50)
is_active = models.BooleanField(default=True)
objects = CarManager()
Использование этого решения всегда возвращает активный набор запросов Car.
Но иногда я также хочу вернуть неактивный набор запросов Car, и я не хочу писать другой ModelManager.
Для разработки,
-
Когда я запускаю,
Car.objects.all() или,
Car.objects.filter(name__contains=’Car’) или,
Car.objects.filter(is_active=True)
Мне нужен только активный набор запросов Car.
-
Когда я запускаю,
Car.objects.filter(is_active=False)
Я хочу иметь неактивный набор запросов Car.
И я хочу добиться этого, используя единый ModelManager и методы по умолчанию (get, filter, all и т. Д.). Почему я хочу этого, потому что он уже использовался во многих местах.
Итак, есть ли какой-либо способ добиться этого? Любые предложения или идеи сердечно приветствуются.
Заранее спасибо за помощь.
Ответ №1:
Итак, после долгих исследований и изучения документации и исходного кода Django я придумал это для метода filter():
class CarManager(models.ModelManager):
def filter(self, *args, **kwargs):
if kwargs.get('is_active') == False:
return super().get_queryset().filter(*args, **kwargs)
return self.get_queryset().filter(*args, **kwargs)
def get_queryset(self):
return super().get_queryset().filter(is_active=True)
Здесь я переопределил метод filter(), чтобы:
- Если передается is_active=False, вызывается родительский (по умолчанию) get_queryset(), за которым следует filter().
- Если is_active не передается или передается is_active=True, вызывается переопределенный метод get_queryset() (который возвращает активный набор запросов Car), за которым следует метод filter().
Если есть какие-либо другие решения или лучшие практики, пожалуйста, укажите их. Спасибо.
Ответ №2:
Боюсь, это невозможно, поскольку вы перезаписываете базовый набор запросов менеджера. Что вы могли бы сделать вместо создания другого менеджера, так это реализовать дополнительный метод, который возвращает набор запросов только с неактивными машинами, что-то вроде:
class CarManager(models.ModelManager):
def get_queryset(self):
return super().get_queryset().filter(is_active=True)
def get_inactive_cars(self):
return super().get_queryset().filter(is_active=False)
А затем замените наборы запросов, в которых вы извлекаете неактивные:
Car.objects.get_inactive_cars()
Комментарии:
1. О, разве невозможно использовать параметры запроса? Например, проверить, используется ли is_active в фильтре, и вернуть соответствующий результат?