您好我的模型如下
class Document(models.Model)
id = models.BigIntegerField(primary_key=True)
text = models.TextField()
class DocumentTags(models.Model):
name = model.CharField(max_length=256)
documents_for_tag = models.ManyToManyField(Document)
现在有了这个,我可以用
获取特定文档的所有标签parent_document = Document.objects.get(id = 1)
parent_document_tags = [x.name for x in parent_document.documenttags_set.all()]
因此parent_document_tags
将包含父文档的所有标记,例如。
["nice" , "unique"]
现在我想接下来让所有Document
标签与这个标签列表紧密匹配。我这样做是为了
Document.objects.filter(documenttags__name__in=parent_document_tags).distinct()
但是,这仅匹配parent_document_tags
中具有完全名称的文档。我希望与__icontains
(或LIKE
)匹配相匹配。如何在不拆分我的标签并逐个进行icontains类型查找的情况下执行此操作。
例如。
d1 has tags : "nice", "unique"
d2 has tags : "nice"
d3 has tags : "nicer"
我希望查询通过将LIKE
链接到查找__icontains
来返回文档d3以及documenttags__name__in
匹配“nicer”。我可以实现这一点,还是我必须有一个for循环并最终过滤掉重复项,如下面的代码所示
related_documents_with_duplicates = []
for tag in parent_document_tags:
docs = Document.objects.filter(documenttags__name__icontains=tag).distinct()
related_documents_with_duplicates.extend(docs)
related_documents_id_unique = list(set([x.id for x in related_documents_with_duplicates]))
return Documents.objects.filter(id__in=related_documents_id_unique)
答案 0 :(得分:0)
实现您想要的方法是使用iregex
field lookup。
首先,获取所需的标签。而不是做:
parent_document = Document.objects.get(id = 1)
parent_document_tags = [x.name for x in parent_document.documenttags_set.all()]
你可以这样做:
parent_document_tags = DocumentTags.objects.filter(documents_for_tag=1).values_list("name",flat=True)
其次,您将获得一个符合您需要的正则表达式。例如,假设您在parent_document_tags
中只有一个名为“tag”的标记。如果我理解你想要什么,你想匹配所有包含(icontains)这个标签的标签的文件。因此,您的查询需要匹配标记为“tag1”标记的文档,“its_a_common_tag”标记...我是对的吗?
因此,这就是如何创建这样的正则表达式(带有正则表达式格式的字符串):
sregex = "|".join(parent_document_tags)
sregex = "(" + sregex + ")"
最后,您想要的查询集如下:
Document.objects.filter(documenttags__name__iregex=sregex)
正则表达式很棒。很难开始使用它们,但是当你了解它们的工作原理时,你将会付出很多努力。
希望它有所帮助!