有效计算物体

时间:2011-06-28 17:20:10

标签: database django query-optimization

我有2个型号:

Category(models.Model):
    name = models.CharField(max_length=30)
    no_of_posts = models.IntegerField(default=0) # a denormalised field to store post count

Post(models.Model):
    category = models.ForeignKey(Category)
    title = models.CharField(max_length=100)
    desc = models.TextField()
    user = models.ForeignKey(User)
    pub_date = models.DateTimeField(null=True, blank=True)  
    first_save = models.BooleanField() 

因为我总是想表明不。每个类别的帖子,我总是数&每次用户以这种方式创建或删除帖子时都存储它们:

   ## inside Post model ##
   def save(self):  
      if not pub_date and first_save:
        pub_date = datetime.datetime.now()
        # counting & saving category posts when a post is 1st published
        category = self.category
        super(Post, self).save()
        category.no_of_posts = Post.objects.filter(category=category).count()
        category.save()

   def delete(self): 
        category = self.category
        super(Post, self).delete()
        category.no_of_posts = Post.objects.filter(category=category).count()
        category.save()
        ........

我的问题是,我们是否可以不使用像:

这样的东西,而不是计算每个对象
 category.no_of_posts += 1 // in save() # and
 category.no_of_posts -= 1 // in delete()

或者是否有更好的解决方案!

哦,我错过了!我更新了帖子模型以包含关系!

1 个答案:

答案 0 :(得分:1)

是的,一个更好的解决方案:

from django.db.models import Count

class CategoryManager(models.Manager):
    def get_query_set(self, *args, **kwargs):
        qs = super(CategoryManager, self).get_query_set(*args, **kwargs)
        return qs.annotate(no_of_posts=Count('post'))

class Category(models.Model):
    ...
    objects = CategoryManager()

由于你没有显示帖子和类别之间的关系,我猜到了Count('posts')部分。你可能不得不摆弄它。

哦,你想要从模型中删除no_of_posts字段。这没有必要。或者,您只需更改注释的名称。

您仍然可以使用category.no_of_posts获取帖子计数,但是您正在让数据库为您做腿部工作。