Django通过多对多ORM对象中的多个标签进行过滤
Posted
技术标签:
【中文标题】Django通过多对多ORM对象中的多个标签进行过滤【英文标题】:Django filtering by multiple tags in many to many ORM object 【发布时间】:2016-09-05 21:16:06 【问题描述】:我有三个模型。 Query
、QueryStringTag
和 Tag
。这些模型是我构建的标签云的一部分。一个Query
可以有很多Tag
s,而Tag
可以有很多Query
s。 Tag
和Query
模型具有连接QueryStringTag
模型的外键,该模型包含有关查询如何与标签关联的所有信息,反之亦然。
这是我的模型...
class Tag(models.Model):
name = models.CharField(max_length=101)
use_count = models.IntegerField(default=1)
class QueryStringTag(models.Model):
tag = models.ForeignKey(Tag, related_name='qstag')
querystring = models.ForeignKey(QueryString, related_name='qsquerystring')
class QueryString(BaseObject):
"""
Query string holds an SQL statement and query properties for execution
"""
server_id = models.IntegerField()
schema = models.CharField(max_length=255, blank=True)
archived = models.BooleanField(default=False)
query = models.CharField(max_length=60000)
variables = models.TextField(blank=True)
created_by = models.ForeignKey(User, related_name='queries_created')
updated_by = models.ForeignKey(User, related_name='queries_last_edited')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField()
touched_by = models.CharField(max_length=1000)
config = models.TextField(blank=True)
runs_started = models.IntegerField(default=0)
runs_completed = models.IntegerField(default=0)
runs_completed_duration = models.IntegerField(default=0) # total number of seconds spent running this query to completion
formats = "pretty_html html json prettyjson csv excel tableau".split()
我目前已经设置好了,所以用户点击标签云中任意数量的标签,标签主键数组就会发送到我的 django 视图,看起来像这样:['12', '14', '15']
我需要使用 Django ORM 来检索与用户单击的所有标签相关联的所有查询。因此,如果用户点击标签“用户”、“游戏”和“卡车”,它应该只带回与用户点击的所有标签相关联的查询。这是AND
关系,而不是OR
关系。意思是“Query1”将与“12”、“14”和“15”相关联。
正确的语法是什么?
【问题讨论】:
如果您在QuerySting
中有Tag
作为ManyToManyField
,那么实现这一点会更容易。拥有QueryStringTag
的目的是什么?
@ShangWang 总而言之,我们的本地开发环境不会接受ManyToManyField
。我不得不这样做。
我只用ManyToManyField
完成了这个,并且有很多与此相关的答案:***.com/questions/13270513/… 和***.com/questions/8618068/…。也许原始 sql 会有所帮助。
@ShangWang 这是ManyToManyField
,接受它只是拼写出来的。 ManyToManyField
所做的只是制作一个中心连接表,就像我正在做的那样。
我当然知道。也许我遗漏了一些东西,但我的观点是你的设计使得使用 django ORM api 很难做到这一点。虽然我还是不太明白是什么阻碍了你使用ManyToManyField
。
【参考方案1】:
qsts_pks = QueryStringTag.objects.filter(tag__pk__in=['12', '14', '15']).values_list('id', flat=True)
queries = QueryString.objects.filter(qsquerystring__pk__in=qsts_pks)
相关文档here 和here
【讨论】:
以上是关于Django通过多对多ORM对象中的多个标签进行过滤的主要内容,如果未能解决你的问题,请参考以下文章
django ORM中的RelatedManager(关联管理器)