带有逻辑运算符的 Tortoise ORM 过滤器
Tortoise ORM filter with logical operators
我有两张桌子
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
在它们的 tags
中应该同时包含 foo
和 bar
?
u = await User.filter(tags__name="t1", tags__value="foo").count()
Tortoise-ORM 为复杂的查询提供 Q objects 逻辑运算符,如 |
(or) 和 &
(and).
您的查询可以这样进行:
u = await User.filter(Q(tags__name="t1") &
(Q(tags__value="foo") | Q(tags__value="bar"))).count()
因为您现在不能 group_by
在 Tortoise ORM 中的注释字段上。
这是使用从
引用的 having
子句的解决方案
u = await User.filter(Q(tags__value="foo") | Q(tags__value="bar"))
.annotate(count=Count("id"))
.filter(count==2)
想法是获取计数等于标签数的记录,在本例中为2
(bar
, foo
)
我有两张桌子
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
在它们的 tags
中应该同时包含 foo
和 bar
?
u = await User.filter(tags__name="t1", tags__value="foo").count()
Tortoise-ORM 为复杂的查询提供 Q objects 逻辑运算符,如 |
(or) 和 &
(and).
您的查询可以这样进行:
u = await User.filter(Q(tags__name="t1") &
(Q(tags__value="foo") | Q(tags__value="bar"))).count()
因为您现在不能 group_by
在 Tortoise ORM 中的注释字段上。
这是使用从
having
子句的解决方案
u = await User.filter(Q(tags__value="foo") | Q(tags__value="bar"))
.annotate(count=Count("id"))
.filter(count==2)
想法是获取计数等于标签数的记录,在本例中为2
(bar
, foo
)