Django, filtragem de consulta do método do modelo
-
21-09-2019 - |
Pergunta
Eu tenho esses modelos:
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
Agora eu quero consultar bares que estão tendo foo ativo como tal:
Bar.objects.filter(foo.is_active())
Estou recebendo erro como
SyntaxError at /
('non-keyword arg after keyword arg'
Como posso conseguir isso?
Solução
Você não pode consultar os métodos ou propriedades do modelo. Use os critérios dentro dele na consulta ou filtre em python usando uma compreensão ou genex da lista.
Outras dicas
Você também pode usar um gerente personalizado. Então você pode executar algo assim:
Bar.objects.foo_active()
E tudo que você precisa fazer é:
class BarManager(models.Manager):
def foo_active(self):
# use your method to filter results
return you_custom_queryset
Confira o documentos.
Eu tive um problema semelhante: estou usando uma visão baseada em classe object_list
E eu tive que filtrar pelo método do modelo. (armazenar as informações no banco de dados não era uma opção porque a propriedade era baseada no prazo e eu teria que criar um Cronjob e/ou ... de jeito nenhum)
Minha resposta é ineficaz e não sei como vai escalar dados maiores; Mas, funciona:
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)
Você não pode filtrar os métodos, no entanto, se o método IS_Active no Foo verificar um atributo no foo, você poder 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)
Pode ser que você possa usar filtro simples, para esse tipo de condições.
Page.objects.filter(category__open=True)