Подтвердить что ты не робот

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" я могу напрямую сравнивать это в запросе фильтра, но для более сложных ситуаций это может быть невозможно. Как мне сделать запрос на основе пользовательских функций?

4b9b3361

Ответ 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)