1

我有两张桌子

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和的用户baralice在这种情况下,应该是1

下面的查询将给我一个单一级别的过滤,但我如何指定user应该在他们的foobar中都有tags

u = await User.filter(tags__name="t1", tags__value="foo").count()
4

2 回答 2

3

Tortoise-ORM为复杂的查询提供了Q 对象|,带有(or) 和&(and) 之类的逻辑运算符。

您的查询可以这样进行:


u = await User.filter(Q(tags__name="t1") & 
                     (Q(tags__value="foo") | Q(tags__value="bar"))).count()
于 2020-12-30T16:06:51.053 回答
0

因为你现在不能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)

于 2021-01-08T08:02:56.253 回答