【问题标题】:Tortoise ORM filter with logical operators带有逻辑运算符的乌龟 ORM 过滤器
【发布时间】:2021-04-07 02:18:24
【问题描述】:

我有两张桌子

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)

现在我想统计同时拥有标签foobar 的用户,在这种情况下是alice,所以应该是1

以下查询将为我提供单级过滤,但我如何指定 user 在其 tags 中应同时包含 foobar

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

【问题讨论】:

    标签: python python-3.x orm tortoise-orm


    【解决方案1】:

    Tortoise-ORM 为复杂的查询提供了Q objects 逻辑运算符,如|(or) 和&(and)。

    您的查询可以这样进行:

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

    【讨论】:

      【解决方案2】:

      由于您现在不能在 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)
      

      这个想法是让记录的计数等于标签的数量,在这种情况下为2barfoo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-03
        • 1970-01-01
        相关资源
        最近更新 更多