Django, фильтрация запросов по модельному методу - PullRequest
62 голосов
/ 17 февраля 2010

У меня есть эти модели:

def Foo(Models.model):
    size = models.IntegerField()
    # other fields

    def is_active(self):
         if check_condition:
              return True
         else:
              return False

def Bar(Models.model):
     foo = models.ForeignKey("Foo")
     # other fields

Теперь я хочу запросить бары, которые имеют активные Foo, как таковые:

Bar.objects.filter(foo.is_active())

Я получаю ошибку, такую ​​как

SyntaxError at /
('non-keyword arg after keyword arg'

Как мне этого добиться?

Ответы [ 5 ]

32 голосов
/ 17 февраля 2010

Нельзя запрашивать методы или свойства модели. Либо используйте критерии в нем в запросе, либо отфильтруйте в Python, используя понимание списка или genex.

29 голосов
/ 26 января 2014

Вы также можете использовать собственный менеджер. Тогда вы можете запустить что-то вроде этого:

Bar.objects.foo_active()

И все, что вам нужно сделать, это:

class BarManager(models.Manager):
    def foo_active(self):
       # use your method to filter results
       return you_custom_queryset

Ознакомьтесь с документами .

18 голосов
/ 05 марта 2013

У меня была похожая проблема: я использую представление на основе классов object_list, и мне пришлось фильтровать по методу модели. (хранение информации в базе данных не было вариантом, потому что свойство было основано на времени, и мне пришлось бы создавать cronjob и / или ... никак )

Мой ответ неэффективен, и я не знаю, как он будет масштабироваться на больших данных; но это работает:

q = Model.objects.filter(...)...
# here is the trick
q_ids = [o.id for o in q if o.method()]
q = q.filter(id__in=q_ids)
10 голосов
/ 17 февраля 2010

Вы не можете фильтровать методы, однако если метод is_active в Foo проверяет атрибут в Foo, вы можете использовать синтаксис с двойным подчеркиванием, например Bar.objects.filter(foo__is_active_attribute=True)

0 голосов
/ 23 апреля 2016
class Page(models.Model):
    category = models.ForeignKey(Category)
    title = models.CharField(max_length=128)
    url = models.URLField()
...

class Category(models.Model):
    ...
    open = models.BooleanField(default=True)

Может быть, вы можете использовать простой фильтр для этого типа условий.

Page.objects.filter(category__open=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...