Ответ 1
Вы не можете запрашивать методы или свойства модели. Либо используйте критерии внутри него в запросе, либо фильтруйте в Python, используя понимание списка или ген.
У меня есть эти модели:
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'
Как я могу это достичь?
Вы не можете запрашивать методы или свойства модели. Либо используйте критерии внутри него в запросе, либо фильтруйте в Python, используя понимание списка или ген.
Вы также можете использовать пользовательский менеджер. Тогда вы можете запустить что-то вроде этого:
Bar.objects.foo_active()
И все, что вам нужно сделать, это:
class BarManager(models.Manager):
def foo_active(self):
# use your method to filter results
return you_custom_queryset
Посмотрите docs.
У меня была аналогичная проблема: я использую класс-представление 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)
Вы не можете фильтровать методы, но если метод is_active в Foo проверяет атрибут на Foo, вы можете использовать синтаксис с двойным подчеркиванием, например Bar.objects.filter(foo__is_active_attribute=True)
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)