web-dev-qa-db-fra.com

Django, filtrage des requêtes à partir de la méthode du modèle

J'ai ces modèles:

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

Maintenant, je veux interroger les bars qui ont des Foo actifs en tant que tels:

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

Je reçois une erreur telle que

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

Comment puis-je atteindre cet objectif?

63
Hellnar

Vous ne pouvez pas interroger des méthodes ou des propriétés de modèle. Soit utiliser les critères qu'il contient dans la requête, soit filtrer dans Python en utilisant une compréhension de liste ou un genex.

33

Vous pouvez également utiliser un gestionnaire personnalisé. Ensuite, vous pouvez exécuter quelque chose comme ceci:

Bar.objects.foo_active()

Et tout ce que vous avez à faire est de:

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

Consultez le docs .

30
0sh

J'ai rencontré un problème similaire: j'utilise la vue basée sur les classes object_list et j'ai dû filtrer par la méthode du modèle. (le stockage des informations dans la base de données n'était pas une option car la propriété était basée sur le temps et je devrais créer un cronjob et/ou ... pas question)

Ma réponse est inefficace et je ne sais pas comment ça va évoluer sur des données plus importantes; mais ça marche:

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)
18
SummerBreeze

Vous ne pouvez pas filtrer sur les méthodes, mais si la méthode is_active sur Foo vérifie un attribut sur Foo, vous pouvez utiliser la syntaxe de double soulignement comme Bar.objects.filter(foo__is_active_attribute=True)

10
Gabriel Hurley
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)

Peut-être que vous pouvez utiliser un filtre simple, pour ce type de conditions.

Page.objects.filter(category__open=True)
0
Sergey Luchko