Django在m2m字段中使用and(&)合并查询

agxfikkp  于 2023-01-06  发布在  Go
关注(0)|答案(2)|浏览(150)

我有这样的模型:

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    tags = models.ManyToManyField(to="tag", related_name="tags", blank=True)

    def __str__(self):
        return self.title

class Tag(models.Model):
    value = models.CharField(max_length=50)
    parent = models.ManyToManyField("Tag", related_name="children", blank=True)
    image = models.ImageField(upload_to="tags", null=True, blank=True)
    
    def __str__(self):
        return self.value

我有一个对象,例如post C,它有标签2和标签3
目前,我不能创建一个组合(q1 & q2)查询,在那里我将能够过滤的条件。
我使用组合查询是因为情况比较复杂(所以双重过滤器不行),我希望能够通过“2或(3和4)“、“(1或2)和(3或4)”等查询进行过滤

>>> q1
<Q: (AND: ('tags__in', '2'))>
>>> q2
<Q: (AND: ('tags__in', '3'))>
>>> Post.objects.filter(q1)
<QuerySet [<Post: post_B>, <Post: post C>, <Post: post D>]>
>>> Post.objects.filter(q2)
<QuerySet [<Post: post C>, <Post: post D>]>
>>> Post.objects.filter(q1 & q2)
<QuerySet []>
>>> str(Post.objects.filter(q1).query)
'SELECT "posts_post"."id", "posts_post"."title", "posts_post"."content" FROM "posts_post" INNER JOIN "posts_post_tags" ON ("posts_post"."id" = "posts_post_tags"."post_id") WHERE "posts_post_tags"."tag_id" IN (2)'
>>> str(Post.objects.filter(q2).query)
'SELECT "posts_post"."id", "posts_post"."title", "posts_post"."content" FROM "posts_post" INNER JOIN "posts_post_tags" ON ("posts_post"."id" = "posts_post_tags"."post_id") WHERE "posts_post_tags"."tag_id" IN (3)'
>>> str(Post.objects.filter(q1 & q2).query)
'SELECT "posts_post"."id", "posts_post"."title", "posts_post"."content" FROM "posts_post" INNER JOIN "posts_post_tags" ON ("posts_post"."id" = "posts_post_tags"."post_id") WHERE ("posts_post_tags"."tag_id" IN (2) AND "posts_post_tags"."tag_id" IN (3))'

我找到的是https://stackoverflow.com/a/8637972/20685072
它说“与Q对象不起作用“

sshcrbum

sshcrbum1#

from django.db.models import Q
query = Q()

对于或条件//

query.add(Q(id__in=[1,2] | Q(id__in=[3,4], query.connector)

如您所要求的2和3 //

query.add(Q(id=2) & Q(id=3), query.connector)

data = Model.objects.filter(query)

这取决于你的要求是什么,你可以根据需要修改它

ecbunoof

ecbunoof2#

我使用原始SQL查询UNION和INTERSECT解决了这个问题

相关问题