Django,从模型方法查询过滤

Hel*_*nar 63 python django django-models django-orm django-queryset

我有这些模型:

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
Run Code Online (Sandbox Code Playgroud)

现在我想要查询具有活动Foo的条形码:

Bar.objects.filter(foo.is_active())
Run Code Online (Sandbox Code Playgroud)

我收到的错误如

SyntaxError at /
('non-keyword arg after keyword arg'
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

Ign*_*ams 33

您无法查询模型方法或属性.在查询中使用其中的条件,或使用列表推导或genex在Python中过滤.

  • 或者将要筛选的值存储在数据库字段中,并在需要时进行更新(通常在保存时).然后,您可以像任何其他字段一样对其进行过滤/排序. (7认同)
  • 如果我重复使用方法查询中的条件,我该如何保持DRY?我的方法对我们的业务逻辑非常重要,如果所说的逻辑发生变化,我就无法承受我的方法.保持干燥是非常重要的. (4认同)

Mil*_*dek 30

您还可以使用自定义管理器.然后你可以运行这样的东西:

Bar.objects.foo_active()
Run Code Online (Sandbox Code Playgroud)

你所要做的就是:

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

查看文档.


Tom*_*cek 19

我有类似的问题:我使用基于类的视图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)
Run Code Online (Sandbox Code Playgroud)

  • 这是我看到保持DRY的唯一方式,但是它会阻碍大型数据集的性能(请记住列表存储在内存中) (5认同)

Gab*_*ley 10

你不能过滤方法,但是如果Foo上的is_active方法检查Foo上的属性,你可以使用双下划线语法,如 Bar.objects.filter(foo__is_active_attribute=True)