带有逻辑运算符的 Tortoise ORM 过滤器

问题描述 投票:0回答:2

我有两张桌子

class User(models.Model):
    id = fields.BigIntField(pk=True)
    name = CharField(max_length=100)
    tags: fields.ManyToManyRelation["Tag"] = fields.ManyToManyField(
        "models.Tag", related_name="users", through="user_tags"
    )

class Tag(models.Model):
    id = fields.BigIntField(pk=True)
    name = fields.CharField(max_length=100)
    value = fields.CharField(max_length=100)
    users: fields.ManyToManyRelation[User]

让我们假设这个虚拟数据

#users
bob = await User.create(name="bob")
alice = await User.create(name="alice")

#tags
foo = await Tag.create(name="t1", value="foo")
bar = await Tag.create(name="t2", value="bar")

#m2m
await bob.tags.add(foo)
await alice.tags.add(foo, bar)

现在我想统计同时拥有

foo
bar
标签的用户,在本例中是
alice
,所以应该是
1

下面的查询将为我提供单级过滤,但如何指定

user
foo
中应同时具有
bar
tags

u = await User.filter(tags__name="t1", tags__value="foo").count()
python python-3.x orm tortoise-orm
2个回答
7
投票

Tortoise-ORM 提供 Q 对象,用于使用逻辑运算符(如

|
(或)和
&
(和))进行复杂查询。

您的查询可以这样进行:


u = await User.filter(Q(tags__name="t1") & 
                     (Q(tags__value="foo") | Q(tags__value="bar"))).count()

3
投票

因为目前您无法在 Tortoise ORM 中的带注释字段上进行

group_by

这是使用
here
引用的 having

子句的解决方案
u = await User.filter(Q(tags__value="foo") | Q(tags__value="bar"))
              .annotate(count=Count("id"))
              .filter(count==2)

这个想法是获取计数等于标签数量的记录,在本例中为

2
(
bar
,
foo
)

© www.soinside.com 2019 - 2024. All rights reserved.