2017-04-06 29 views
0

这是我在我的小项目在合适的时候使用.Count之间的()在Django ORM

class Tag(models.Model): 
    name = models.CharField(max_length=200) 

class Post(models.Model): 
    content = models.CharField(max_length=200) 
    tags = models.ManyToManyField(Tag) 
    location = models.PointField(null=True, blank=True) 

标签列表是给我(最多3个)的车型。我需要找到每个这些标签在Post上出现的次数标签。让说[“搞笑”,“怪才”,“高科技”]

为了得到标记计数我做

for tag in tags: 
     tag_data[tag] = Post.objects.filter(
      tags__name=tag, 
      location__distance_lte=(
       pnt, D(km=distance))).count() 

然后我使用下面的查询获取所有的POST数据。

posts = Post.objects.filter(
      tags__name__in=tags, 
      location__distance_lte=(pnt, D(km=distance))) 

我已经在函数结尾的帖子上循环。

for post in posts: 
    #some logic 

所以我知道我有那里的标签数据。不需要像上面那样进行单独的数据查询来查找计数。但我想通了,如果我想找到for循环内的标签数,我需要1个循环内循环。

for post in posts: 
    #some logic 
    for tag in post.tags: 
     #some logic 

所以我的问题哪一个更有效率在这里。使用.count()像我一样进行抓取或嵌套循环。

+0

什么是'tag_data [em_id]''中的em_id'? –

+0

这是一个错字。更新 –

+0

据我所知,你要计算已在特定“Post”中标记的“标签”的数量。正确?或者你想要统计已经使用了多少'Post'标签?你想要计算的是什么? –

回答

2

在Django的ORM有一些所谓的聚合正在使用.annotate().aggregate()方法来添加你要找的查询功能。 (Docs on Aggregation)。

有很多的你如何能做到的事情,如让一个CountAvgSum和more.This也可以做例子在整个许多一对多的关系,就像在你的情况。

There's even an example在与您的案例非常相似的文档中。

例如,如果您要检索书籍列表,您可能想知道有多少作者对每本书作出贡献。每本书都与作者有多对多的关系;我们希望总结QuerySet中每本书的这种关系。

要计算的Post一个Tag量已经出现在你只是这样做:

# Add any arguments you want to the filter() to narrow down the Tag query set. 
tags = Tags.objects.filter().annotate(Count('post_set')) 
# You access it as post_set__count 

编辑:

根据您提供的,要添加条件的评论注释和查询,只能计算半径内的帖子。要做到这一点,你可以使用Django所谓的Conditional Expressions

借助条件表达式,您可以为您的.annotate()添加条件。

例子:

tags = Tags.objects.filter().annotate(Count(
     Case(When(post_set__location="1", then=1), output_field=IntegerField()) 
)) 

请仔细阅读文档,了解你的情况来使用它的正确方法。您可以看到Conditional Expressions with Aggregations

+0

我明白了。但我很困惑在帖子上应用过滤器的位置。正如你所看到的,我只需要满足位置条件的帖子(* location__distance_lte =(pnt,D(km = distance))*)。 –

+0

你以前写过,我们应该忽略位置字段......但是如果我理解正确,你想要计算'标签'存在的'Post'的数量,但只计算半径内的'Post' ?所以你不希望总的标签数量,你想限制它'Post'的位置? –

+0

是的。并抱歉误导。当我说忽略我的意思就是把它当作过滤器领域。我想要标签数量并通过发布位置限制 –

相关问题