gpt4 book ai didi

Django - 使用中间表对 ManyToMany 字段进行注释

转载 作者:行者123 更新时间:2023-12-01 04:04:39 25 4
gpt4 key购买 nike

我正在为 Django 项目构建一个小型搜索系统(是的,我知道,已经有很多产品在这样做,但我想尝试一下,只是为了好玩)。
我基本上有以下型号:

class Word(models.Model):
""" A searchable word.
We only store the slugified value
"""
slug = models.SlugField(unique = True)

class Searchable(models.Model):
""" Superclass for Searchable objects.
"""
words = models.ManyToManyField(
Word,
through='WordCount')

class WordCount(models.Model):
""" Occurences of a word in a Searchable object.
"""
word = models.ForeignKey(Word)
item = models.ForeignKey(Searchable)
count = models.IntegerField()

例如,我使用文本“Hello StackOverflow,我有一个 Django 问题”创建了一个对象 Page(子类化 Searchable)。系统将为这句话中的每个单词创建一个 Word 实例,并为每个单词创建一个 WordCount 实例,表示每个单词在文本中出现一次。

进行查询以获取包含一个更多单词的所有 Searchable 实例工作正常(searchable_text 提取单词并从中创建一个列表):
def search(query)
tokens = searchable_text(query)
words = Word.objects.filter(
reduce(operator.or_,
[models.Q(slug__contains = t)
for t in tokens]))

return Searchable.objects.filter(words__in = words)

现在我想做的是使用中间关系来对结果进行排序。我想保留一个 QuerySet 以便以下代码不起作用,但给出了我想要做什么的想法(使用丑陋的补丁来制作注释):
def search(query)
tokens = searchable_text(query)
words = Word.objects.filter(
reduce(operator.or_,
[models.Q(slug__contains = t)
for t in tokens]))
results = []
for obj in Searchable.objects.filter(words__in = words):
matching_words = obj.wordcount_set.filter(word__in = words)
obj.weight = sum([w.count for w in matching_words])
results.append(obj)

return sorted(results,
reverse = True,
key = lambda x: x.weight)

所以基本上:
- 我得到了包含在查询中的所有 Word 对象(或部分匹配,如果我搜索“Stack”,单词“StackOverflow”将被考虑在内)
- 我得到所有与这些词有关系的对象
- 对于每个对象,我选择与先前计算的 Word 列表中的 Word 相关的所有相关 WordCount 对象,然后计算“计数”属性的总和并将其存储为注释“权重”
- 我根据“重量”对我的元素进行分类

我不知道这对 QuerySet 是否可行,但我想在之后保留一些额外操作的格式(例如过滤掉一些结果)。

我知道有很多改进的可能,但这将是一个好的开始。

感谢您的回答,
文森特

最佳答案

尝试

Searchable.objects.filter(words__in=words).annotate(
weight=models.Sum('wordcount__count')).order_by('-weight')

关于Django - 使用中间表对 ManyToMany 字段进行注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10258960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com