结合__icontains查找与在Django __in查找获取包含在名称数组名称的一部分的对象(C

2019-10-28 13:19发布

你好我的型号如下

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"

我希望查询与返回文档D3以及LIKE通过级联匹配“更好” __icontains到查找documenttags__name__in 。 我能做到这一点还是我必须有一个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)

Answer 1:

acomplishing你想要的东西的方式是使用iregex现场查找 。

首先,得到你想要的标签。 而不是做的:

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所谓的“标签”。 如果我知道你想什么,你想匹配的是有标签包含(icontains)这个标签的所有文件。 所以,你的查询需要匹配标记为“标签1”标记的文件,“its_a_common_tag”标签......是吗?

所以,这是你可以创建一个这样的正则表达式(正则表达式与格式的字符串):

sregex = "|".join(parent_document_tags)
sregex = "(" + sregex + ")"

最后,你想查询集将是这样的:

Document.objects.filter(documenttags__name__iregex=sregex)

正则表达式是巨大的。 这是很难开始使用它们,但是当你了解他们的工作,你会赚了很多努力。

希望能帮助到你!



文章来源: Combine __icontains lookup with __in lookup in django to get objects that contain part of name in names array