如何在没有 for 循环的情况下 annotate/aggregate 列表中的每个项目(Django)

How to annotate/aggregate each item in a list without for loops (Django)

我有一个列表 s,它是从 class 标签中的模型字段 "sentence" 保存和过滤的,一个模型字段 "label" 包含列表 s 中的每个项目,即一个post 句子 s 中每个项目的每个项目。我想聚合或注释 "label" 中的项目,这些项目位于字段句子中的列表中,最大出现次数为第三个字段 "labelnames"。例如,在字段语句中列出 s; ["a"、"green"、"car"]。对于 classes 中 s 中的每个元素,s 出现; "a" 例如,计算 "a" 在所有 post 中的最大出现次数和 "labelnames" 中的句子和字段。我想知道是否有更好的方法来聚合它而不是循环 list 中的元素然后用 "labelname" 和 "label" 注释或聚合它们?

对于 S 中的每个元素,"a"、"green"、"car",仅当其中一个元素与 S 位于 post 中(它们被保存in class Label () 一个pos"a" in field label and list s in field sentence, second post "green" in field label and list s in sentence 等等),使用字段 labelname 中的元素聚合或注释元素,例如 "a" with labelname A if labelname A or B depending on max count of all elements "a" with labelname fieldvalue "A" has a higher maximumvalue比所有标签 "a" 的标签名称字段值 "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

# 这给了我一个 post 的 pk=int(t.id),"a" 和句子出现在其中。我#like all posts "a","green","a car"加上句子s和最大labelname。 # 在 models.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) 

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

这样做的传统方法是让第二个 table 包含所有单词,例如:

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)

因此,对于您插入的每个标签,还要插入 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 filter on reverse foreign key".. 你会发现这是 django 的一个常见问题,人们正在努力更有效地解决它。

我要补充的另一件事是,您可以使用 ManyToMany 关系来执行此操作,从而只存储每个唯一的单词一次。在某些方面效率更高,在其他方面效率较低...