如何在没有for循环的情况下注释/聚合列表中的每个项目(Django)

时间:2015-10-29 20:02:39

标签: python django django-models annotations aggregate-functions

我有一个列表s,它是从modelfield"句子"中保存和过滤的。在类Label中,一个modelfield"标签"包含列表s中的每个项目,即句子s中每个项目的每个项目一个帖子。我想在"标签"中汇总或创建项目。在字段句子中的列表s中,第三个字段的最大出现次数为#34; labelnames"。例如,字段句中的列表s; [" a","绿色","汽车"]。对于类中s中的每个元素都会出现; ""例如,计算" a"的最大出现次数。在所有帖子中包含" labelnames"中的句子和字段。我想知道是否有更好的方法来聚合它而不是在列表s中循环元素,然后使用" labelname"来注释或聚合它们。和"标签" ?

对于S中的每个元素," a","绿色"," car",仅当其中一个元素位于带有S的帖子中时(&& #39;重新保存在类Label()中一个pos" a"在字段标签中,列表s在字段句中,第二个帖子"绿色"在字段标签中,列表s在句子中等等),使用字段labelname中的元素聚合或注释元素,例如" a"带有labelname A if labelname A或B取决于所有元素的最大数量" a" with labelname fieldvalue" A"具有比所有标签更高的最大值" a" with labelname fieldvalue" B"保存在数据库中。

#I've retrived id for sentence s by for label "a"
str_ = "a"
t = Label.objects.filter(label__startswith=str_).filter('label')
# get sentence that t is associated with
s =  OneLabelingPCS.objects.get(pk=int(t.id)).sentence  
            #print

#这给了我一个帖子的pk = int(t.id)" a" 。句子出现在。我' d#像所有帖子" a","绿色","汽车"句子s和最大标签名称。    #insts.py

class Label(models.Model):


 sentence = models.CharField(max_length=200) # <-- contains list s
  label = models.CharField(max_length=200) # <-- contains each item in s, one item per post 
labelname = models.CharField(max_length=200) 

1 个答案:

答案 0 :(得分:1)

就Django而言,'sentence'是一个字符串..它也作为字符串存储在数据库中..所以Django和数据库都不了解你放在那里的列表的元素

这样做的传统方法是使用包含所有单词的第二个表格,例如:

class Label(models.Model):
    label = models.CharField(max_length=200) 
    labelname = models.CharField(max_length=200)

class LabelWord(models.Model):
    word = models.CharField(max_length=30)
    position = models.IntegerField()
    label = models.ForeignKey(Label)

因此,对于您插入的每个Label,还要插入LabelWord记录,例如:

label = Label(label="fooo", labelname="FOO Name")
label.save()

position = 0
for word in ('a', 'green', 'car'):
    LabelWord(label=label, word=word, position=position).save()
    position += 1

好了,现在你想找到所有带有'car'字样的标签? Django并没有明白如何做到这一点..但这是简单(但不是超级高效)的方式:

labels = Label.objects.filter(
    pk__in=LabelWords.objects.filter(word='car').values_list('label_id', flat=True)
)

对于相对少量的数据,这将正常工作。搜索“反向外键上的django过滤器”..你会发现django常见的问题是人们试图更有效地解决这个问题。

我要添加的另一件事是你可以用ManyToMany关系来做到这一点,因此只存储一次唯一的单词。在某些方面效率更高,在其他方面效率更低......