Django,从模型方法进行查询过滤

发布于 2024-08-21 23:52:18 字数 525 浏览 4 评论 0原文

我有这些模型:

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 的 Bars:

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

我收到错误,例如

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

如何实现此目的?

I have these models:

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

Now I want to query Bars that are having active Foo's as such:

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

I am getting error such as

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

How can I achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

人│生佛魔见 2024-08-28 23:52:18

您无法查询模型方法或属性。可以在查询中使用其中的条件,也可以使用列表理解或 Genex 在 Python 中进行过滤。

You cannot query against model methods or properties. Either use the criteria within it in the query, or filter in Python using a list comprehension or genex.

三月梨花 2024-08-28 23:52:18

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

Bar.objects.foo_active()

你所要做的就是:

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

查看 文档

You could also use a custom manager. Then you could run something like this:

Bar.objects.foo_active()

And all you have to do is:

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

Check out the docs.

烟酉 2024-08-28 23:52:18

我遇到了类似的问题:我正在使用基于类的视图 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)

I had similar problem: I am using class-based view object_list and I had to filter by model's method. (storing the information in database wasn't an option because the property was based on time and I would have to create a cronjob and/or... no way)

My answer is ineffective and I don't know how it's gonna scale on larger data; but, it works:

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)
半城柳色半声笛 2024-08-28 23:52:18

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

You can't filter on methods, however if the is_active method on Foo checks an attribute on Foo, you can use the double-underscore syntax like Bar.objects.filter(foo__is_active_attribute=True)

通知家属抬走 2024-08-28 23:52:18

显然,正如 Ignacio Vazquez-Abrams 指出的那样,您无法在视图中查询模型方法。相反,我会在视图中应用所需的过滤器逻辑。

例如,当 check_condition 是日期范围时:

class BarView(ListView):
    model = Bar
    template_name = "app/bar.html"

    def get_queryset(self):
        # Filter for a condition (here the condition is a date range)
        now = timezone.now().date()
        return Bar.objects.filter(foo__start_date__lte=now, foo__end_date__gte=now)

Apparently, and as Ignacio Vazquez-Abrams pointed out, you cannot query against model methods in a view. Instead, I would apply the required filter logic in the view.

For instance, when check_condition is a date range:

class BarView(ListView):
    model = Bar
    template_name = "app/bar.html"

    def get_queryset(self):
        # Filter for a condition (here the condition is a date range)
        now = timezone.now().date()
        return Bar.objects.filter(foo__start_date__lte=now, foo__end_date__gte=now)
等风来 2024-08-28 23:52:18

一种选择是使用 django-denorm 本质上动态创建模型字段:

@denorm.denormalized(models.BooleanField, null=True, default=False)
@denorm.depend_on_related("Bar")
def is_active(self):
    # return something

然后您可以按 foo__is_active=True 过滤。

添加此后,使用 manage.py makemigrationsmanage.py migratemanage.py denorm-init 准备数据库。这可能不是最好的解决方案,因为模型应该主要代表数据库结构,本身不做太多工作,但这就是我的前任所做的。

One option is to use django-denorm to essentially dynamically create a model field:

@denorm.denormalized(models.BooleanField, null=True, default=False)
@denorm.depend_on_related("Bar")
def is_active(self):
    # return something

Then you can filter by foo__is_active=True.

After adding this, use manage.py makemigrations and manage.py migrate and manage.py denorm-init to prepare the database. This may not be the best solution because models should be primarily representing the database structure, not doing much work themselves, but it's what my predecessor did.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文