Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django依靠多对多_Django_Django Orm - Fatal编程技术网

Django依靠多对多

Django依靠多对多,django,django-orm,Django,Django Orm,我有以下模型: class Article(models.Model): title = models.TextField(blank=True) keywords = models.ManyToManyField(Keyword, null=True, blank=True) class Keyword(models.Model): keyword = models.CharField(max_length=355, blank=True) 我想统计一下每个关键词有

我有以下模型:

class Article(models.Model):
    title = models.TextField(blank=True)
    keywords = models.ManyToManyField(Keyword, null=True, blank=True)

class Keyword(models.Model):
    keyword = models.CharField(max_length=355, blank=True)
我想统计一下每个关键词有多少篇文章。本质上,我希望有一个关键字列表,我可以得到每个关键字的计数,从而给它一个相对的权重

我试过:

keyword_list=Article.objects.all().annotate(key_count=Count('keywords__keyword'))
但是

只是好像给了我每篇文章的不同关键词的数量?这是一种反向查找吗

任何帮助都将不胜感激

更新

所以我成功了:

def keyword_list(request):
    MAX_WEIGHT = 5
    keywords = Keyword.objects.order_by('keyword')
    for keyword in keywords:
        keyword.count =  Article.objects.filter(keywords=keyword).count()
    min_count = max_count = keywords[0].count
    for keyword in keywords:
        if keyword.count < min_count:
            min_count = keyword.count
        if max_count > keyword.count:
            max_count = keyword.count 
    range = float(max_count - min_count)
    if range == 0.0:
        range = 1.0 
    for keyword in keywords:
        keyword.weight = (
            MAX_WEIGHT * (keyword.count - min_count) / range
        )
    return { 'keywords': keywords }
def keyword_list(request):
    MAX_WEIGHT = 5
    keywords_with_article_counts = Keyword.objects.all().annotate(count=Count('keyword_set'))
    # get keywords and count limit to top 20 by count
    keywords = keywords_with_article_counts.values('keyword', 'count').order_by('-count')[:20]
    min_count = max_count = keywords[0]['count']
    for keyword in keywords:
        if keyword['count'] < min_count:
            min_count = keyword['count']
        if max_count < keyword['count']:
            max_count = keyword['count']             
    range = float(max_count - min_count)
    if range == 0.0:
        range = 1.0
    for keyword in keywords:
        keyword['weight'] = int(
            MAX_WEIGHT * (keyword['count'] - min_count) / range
        )
    return { 'keywords': keywords}
def关键字列表(请求):
最大重量=5
关键字=关键字.objects.order\u by('Keyword')
对于关键字中的关键字:
keyword.count=Article.objects.filter(keywords=keyword).count()
最小计数=最大计数=关键字[0]。计数
对于关键字中的关键字:
如果关键字.count<最小计数:
最小计数=关键字.count
如果最大计数>关键字计数:
最大计数=关键字.count
范围=浮动(最大计数-最小计数)
如果范围==0.0:
范围=1.0
对于关键字中的关键字:
关键字。权重=(
最大重量*(关键字.计数-最小计数)/范围
)
返回{“关键字”:关键字}
但是该视图会导致大量查询。我已经尝试过实施这里给出的建议(谢谢),但这是目前唯一有效的方法。然而,我一定是做错了什么,因为我现在有400多个查询

更新

哇!终于让它工作了:

def keyword_list(request):
    MAX_WEIGHT = 5
    keywords = Keyword.objects.order_by('keyword')
    for keyword in keywords:
        keyword.count =  Article.objects.filter(keywords=keyword).count()
    min_count = max_count = keywords[0].count
    for keyword in keywords:
        if keyword.count < min_count:
            min_count = keyword.count
        if max_count > keyword.count:
            max_count = keyword.count 
    range = float(max_count - min_count)
    if range == 0.0:
        range = 1.0 
    for keyword in keywords:
        keyword.weight = (
            MAX_WEIGHT * (keyword.count - min_count) / range
        )
    return { 'keywords': keywords }
def keyword_list(request):
    MAX_WEIGHT = 5
    keywords_with_article_counts = Keyword.objects.all().annotate(count=Count('keyword_set'))
    # get keywords and count limit to top 20 by count
    keywords = keywords_with_article_counts.values('keyword', 'count').order_by('-count')[:20]
    min_count = max_count = keywords[0]['count']
    for keyword in keywords:
        if keyword['count'] < min_count:
            min_count = keyword['count']
        if max_count < keyword['count']:
            max_count = keyword['count']             
    range = float(max_count - min_count)
    if range == 0.0:
        range = 1.0
    for keyword in keywords:
        keyword['weight'] = int(
            MAX_WEIGHT * (keyword['count'] - min_count) / range
        )
    return { 'keywords': keywords}
def关键字列表(请求):
最大重量=5
关键字与文章计数=关键字.objects.all().annotate(计数=计数('Keyword\u set'))
#按计数将关键字和计数限制设置为前20名
关键词=包含文章计数的关键词。值('keyword','count')。排序依据('-count')[:20]
最小计数=最大计数=关键字[0]['count']
对于关键字中的关键字:
如果关键字['count']
由于您需要包含每个关键字的文章数量,因此必须采用另一种方式:

>>> Keyword.objects.all().annotate(article_count=models.Count('article'))[0].article_count
2

我不知道你会如何有效地完成它,但如果你需要完成它

keywords = Keyword.objects.all()
for keyword in keywords:
  print 'Total Articles: %d' % (Article.objects.filter(keywords=keyword).count())

这与来自的答案相同,但有一点上下文,其中
article\u set
是反向多对多关系对象的
相关名称

keywords_with_article_counts = Keyword.objects.all().annotate(article_count=Count('article_set'))
为了说明结果,返回
.values()

这将返回一个类似以下内容的词典列表:

[{'article_count': 36, 'keyword': u'bacon'}, 
 {'article_count': 4, 'keyword': u'unicorns'}, 
 {'article_count': 8, 'keyword': u'python'}]

这确实是正确的答案,但可能需要一些解释。您可以将其简化为
关键字.objects.all().annotate(Count('article'))[0]。article\u Count
谢谢。这使它更清晰了一点,尽管我仍然难以将其整合到我的视图中(参见我编辑的问题)。如果我返回一个字典,那么这个视图就必须有很大的不同,不是吗?你可以返回
关键字以及文章计数
QuerySet作为你的视图。我刚刚演示了
.values()
方法的使用,它允许您返回所需字段的字典,而不是模型实例。这只是为了说明
article\u count
的结果,如果这让人困惑的话,很抱歉。我现在有了一个修改版本的shell,但是根据我上面的观点,当我试图将计数转换为权重并将关键字作为对象传递时,我几乎没有迷失方向。有关于如何集成此功能的提示吗?