【问题标题】:How to annotate/aggregate each item in a list without for loops (Django)如何在没有for循环的情况下注释/聚合列表中的每个项目(Django)
【发布时间】:2016-01-30 03:28:33
【问题描述】:

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

对于 S 中的每个元素,“a”、“green”、“car”,仅当其中一个元素在带有 S 的帖子中时(它们保存在类 Label() 中的一个 pos"a" 字段中label 和 list s in field sentence, second post "green" in field label and list s in sentence 依此类推),使用字段 labelname 中的元素聚合或注释元素,例如如果 labelname A 或 B,则使用 labelname A 的 "a"取决于标签名字段值为“A”的所有元素“a”的最大计数,其最大值高于保存在数据库中的所有标签名字段值为“B”的标签“a”。

#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”和句子。我希望所有帖子“a”、“green”、“a car”都带有句子 s和最大标签名。 # 在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) 

【问题讨论】:

  • 可以显示您想要完成的任务吗?你的解释不是很清楚

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


【解决方案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

好的,现在您要查找所有带有“汽车”一词的标签吗? 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 关系执行此操作,因此每个唯一单词只存储一次。在某些方面效率更高,在其他方面效率更低......

【讨论】:

  • 非常感谢,有了这个我可以得到与给定句子 s 相关联的每个标签和标签 pk。
  • 注意我刚刚更改了代码.. 我使用 'id' 而应该是 'label_id'
  • 是的,没错,我将每个单词存储在一个还包含标签 ID 的记录中。所以我查询了与某个单词相关的所有label_id,然后获取与该组id匹配的所有标签记录。
猜你喜欢
  • 1970-01-01
  • 2019-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 2011-08-15
  • 2019-10-10
  • 2018-08-05
相关资源
最近更新 更多