Django: запрос фильтра на основе пользовательской функции
У меня есть функция, встроенная в класс модели Django, и я хочу использовать эту функцию для фильтрации результатов моих запросов.
class service:
......
def is_active(self):
if datetime.now() > self.end_time:
return False
return True
Теперь я хочу использовать эту функцию в моем фильтре запросов, что-то вроде
nserv = service.objects.filter(is_active=True)
Я знаю, что для этого простого случая "is_active" я могу напрямую сравнивать это в запросе фильтра, но для более сложных ситуаций это может быть невозможно. Как мне сделать запрос на основе пользовательских функций?
Ответы
Ответ 1
Я бы предложил вам использовать пользовательский менеджер для своего класса, например, вы могли бы использовать:
nserv = service.objects.are_active()
Это будет достигнуто с помощью чего-то вроде:
class ServiceManager(models.Manager):
def are_active(self):
# use your method to filter results
return you_custom_queryset
См. пользовательские менеджеры
Ответ 2
Возможно, вам это не удастся, вместо этого вы можете отправить запрос с помощью списка или выражение генератора.
Например:
[x for x in Q if x.somecond()]
Ответ 3
У меня была аналогичная проблема. Проблема в том, что я должен был вернуть экземпляр QuerySet. Быстрое решение для меня заключалось в том, чтобы сделать что-то вроде:
active_serv_ids = [service.id for service in Service.objects.all() if service.is_active()]
nserv = Service.objects.filter(id__in=active_serv_ids)
уверен, что это не самый красивый и эффективный способ сделать это, но я работаю для меня.
более подробный способ сделать это:
active_serv_ids = []
for service in Service.objects.all():
if service.is_active():
active_serv_ids.append(service.id)
nserv = Service.objects.filter(id__in=active_serv_ids)
Ответ 4
Ответ Ignacio интересен, но он не возвращает запрос. Это делает:
def users_by_role(role):
users = User.objects.all()
ids = [user.id for user in users if user.role == role]
return users.filter(id__in=ids)