模型/经理问题以组织查询

时间:2010-03-18 15:36:29

标签: django django-models

我有一个应用程序来计算同一数据库中每个网站的对象访问次数。

class SimpleHit(models.Model):
    """
    Hit is the hit counter of a given object
    """
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    site = models.ForeignKey(Site)

    hits_total = models.PositiveIntegerField(default=0, blank=True)

    [...]

class SimpleHitManager(models.Manager):
    def get_query_set(self):
        print self.model._meta.fields
        qset = super(SimpleHitManager, self).get_query_set()
        qset = qset.filter(hits__site=settings.SITE_ID)
        return qset

class SimpleHitBase(models.Model):
    hits = generic.GenericRelation(SimpleHit)

    objects = SimpleHitManager()

    _hits = None

    def _db_get_hits(self, only=None):
        if self._hits == None:
            try:
                self._hits = self.hits.get(site=settings.SITE_ID)
            except SimpleHit.DoesNotExist:
                self._hits = SimpleHit()
        return self._hits

    @property
    def hits_total(self):
        return self._db_get_hits().hits_total

    [...]

    class Meta:
        abstract = True

我有一个类似的模型:

class Model(SimpleHitBase):
    name = models.CharField(max_length=255)
    url = models.CharField(max_length=255)
    rss = models.CharField(max_length=255)
    creation = AutoNowAddDateTimeField()
    update = AutoNowDateTimeField()

所以,我的问题是这样的:当我调用Model.objects.all()时,我希望有一个SQL请求(不是两个)。在这种情况下:一个用于Model以获取信息,一个用于命中以获得计数器(hits_total)。这是因为我无法直接调用hits.hits_total(由于SITE_ID?)。我试过了select_related,但它似乎不起作用......

问题: - 如何像(SELECT hits.hits_total, model.* FROM [...])一样自动添加列到查询集? - 或者在模型中使用功能select_related

我希望这个模型可以在所有其他现有模型上插入。

2 个答案:

答案 0 :(得分:1)

我终于找到了答案,我已经更改了我的经理,现在列将添加到数据库请求中。

    select = {
        'hits': 'hits_simplehit.hits_total',
    }
    qset = super(SimpleHitManager, self).get_query_set()
    qset = qset.extra(select=select)
    qset = qset.filter(hits_rel__site=settings.SITE_ID)
    return qset

谢谢:)

答案 1 :(得分:0)

您是否考虑过对每个对象执行单个数据库命中的性能影响?

如果您有少量的对象,请将整个表保留在内存中,并将磁盘写入作为异步(后台)任务发送。