Python 通过使用两个具有ForeignKey关系的模型通过共享文本标记使用QuerySet API对django对象进行分组

Python 通过使用两个具有ForeignKey关系的模型通过共享文本标记使用QuerySet API对django对象进行分组,python,django,orm,django-models,django-queryset,Python,Django,Orm,Django Models,Django Queryset,您好,我正在尝试编写一个django webapp,它位于遗留数据库之上,因此我无法控制太多的模型字段,也无法使用新模型实现功能 我有很多文档都有用户指定的逗号分隔标记。我想根据共享标记对“相关”文档进行分组 # Model to express legacy table class Document(models.Model): id = models.BigIntegerField(primary_key= True) metadata_id = models.CharFie

您好,我正在尝试编写一个django webapp,它位于遗留数据库之上,因此我无法控制太多的模型字段,也无法使用新模型实现功能

我有很多文档都有用户指定的逗号分隔标记。我想根据共享标记对“相关”文档进行分组

# Model to express legacy table
class Document(models.Model):
    id = models.BigIntegerField(primary_key= True)
    metadata_id = models.CharField(max_length=384)
    tags_as_csv = models.TextField()

# Created new Model tag_text extracted from tags_as_csv
class Tagdb(models.Model):
    tagid = models.BigIntegerField(primary_key=True)
    referencing_document = models.ForeignKey(Document)
    tag_text = models.TextField(blank=True)
因此,文件将包含:

Document : 
id = 1 , 
metadata_id = "a1ee3df3600c6f77a6e851781f7e70c6" , 
tags_as_csv = "raw-data , high temperature , important"
Tagdb将有如下条目

id , referencing_document , tag_text
1  , 1 , "raw-data" 
2  , 1 , "high temperature"
3  , 1 , "important"
4  , 2 , "important"
5  , 2 , "processed-data"
6  , 3 , "important"
7  , 4 , "processed-data"
现在,我想提取与父文档对应的标记匹配的所有文档对象。我正在使用下面的get_queryset方法执行此操作

   def get_queryset(self, **kwargs):
        parent_document = Document.objects.get(id=self.kwargs['slug'])
        tags_in_parent_document = [x.tag_text for x in Tagdb.objects.filter(referencing_document=parent_document.id)]
        # This will contain all the Document ids that match all the tags
        queryset_with_duplicates = []
        for tag in tags_in_parent_document:
            queryset_with_duplicates.extend([x.referencing_document.id for x in Tagdb.objects.filter(tagtext__icontains=tag)])

        # Make sure we have only unique ids
        queryset_unique = set(queryset_with_duplicates)

        # Get all the Document objects 
        queryset = Document.objects.filter(id__in=queryset_unique)

        return queryset

我的问题是:有没有更好的办法。我能否以某种方式获取包含父文档中所有标记的所有文档并过滤掉重复的文档(因为多个文档包含相同的标记)。

您最好创建两个附加模型:一个用于标记,另一个用于标记和文档之间的链接。如果是不可接受的原因,您可以使用以下内容:

Document.objects.filter(tagdb__tag_text__in=doc.tags_as_csv.split(' , ')).distinct()

另外,添加用于获取/设置标记的模型方法,这将简化任何可能的重构。

我按照您的建议创建了一个多域模型,将两者联系在一起。按照您的建议,使用新创建的表更容易,特别是像“自动创建字段”这样的查找,它是由ManyToManyField映射产生的。然而,我遇到了一个新的“问题”。我想知道如何将_in查找与_icontains查找结合起来。