注释在Django与通用的关系

问题描述 投票:1回答:1

我使用django-hitcount相符命中我的数据库对象。我想通过对象计数命中,以确定哪些对象在一定时间范围内的点击率最高。该应用程序有兴趣在这里两种型号:

class Hit(models.Model):
    created         = models.DateTimeField(editable=False)
    ip              = models.CharField(max_length=40, editable=False)
    session         = models.CharField(max_length=40, editable=False)
    user_agent      = models.CharField(max_length=255, editable=False)
    user            = models.ForeignKey(User,null=True, editable=False)
    hitcount        = models.ForeignKey(HitCount, editable=False)

class HitCount(models.Model):
    hits            = models.PositiveIntegerField(default=0)
    modified        = models.DateTimeField(default=datetime.datetime.utcnow)
    content_type    = models.ForeignKey(ContentType,
                        verbose_name="content cype",
                        related_name="content_type_set_for_%(class)s",)
    object_pk       = models.TextField('object ID')
    content_object  = generic.GenericForeignKey('content_type', 'object_pk')

“命中”记录每打一个时间戳,而HitCount门店总体命中数。要根据对象和时间范围内获得的点击,我需要做到以下几点:

过滤器通过计数每content_object命中日期创建的计数数命中顺序(上述过滤时间范围内)上述返回content_object和计数计算

这可能是非常昂贵的,所以我计划calcing /缓存每天一次。

作为第一步,我想,不论时间范围的计数每content_object的点击次数。

limited_hc = Hit.objects.all().values('hitcount__content_object').annotate(count = Count('hitcount__object_pk'))

我立即运行到一个问题:

无法解析关键字“hitcount__content_object”到现场。选项包括:创建,hitcount,ID,IP,会话,用户,USER_AGENT

一些挖后,我发现annotation and generic relations do not work well together。如果我使用的,而不是content_object object_pk,它工作正常,但后来我没有对象的名称。

所以我的问题:什么是替代达到同样的效果?如何通过组对象,但也保留了名字?

我有模型(CONTENT_TYPE)和ID(object_pk),所以我总是可以单独扯这些,但似乎不雅。 。 。

django annotations count generic-relations
1个回答
1
投票

这将可能是更有效的为您的目的是增加一个通用的关系Hit模型:

class Hit(models.Model):
    ...
    object_id = models.PositiveIntegerField()
    content_type = models.ForeignKey(ContentType)
    content_object = generic.GenericForeignKey('content_type', 'object_id')

直接命中,然后运行计数()查询:

t = ContentType.objects.get_for_model(the_object_being_hit)
id = the_object_being_hit.id
count = Hit.objects.filter(
                   created__range=(from_timestamp, to_timestamp),
                   content_type = t,
                   object_id = id
                 ).count()

您可以使用Django南迁系统修改命中数的模式。您也可以尝试后猴子修补它的元类,或者只是定义满足您的需求,更好的自己的模型来子类命中。

编辑如果你想指望一整类对象或几类命中,那么你可以有:

count = Hit.objects.filter(
                     created__range = myrange,
                     content_type__in = set_of_types
                   ).count()

其中set_of_types可以是与get_for_model构造的列表呼叫或由ContentType表的直接滤波而获得的查询集。

计数()方法的好处是,它使得在数据库中,这是更快的计数发生。

要获得通过CONTENT_TYPE细分试试这个:

counts = Hit.objects.filter(
                   created__range = myrange
                ).values(
                   'content_type'
                ).annotate(
                   Count('content_type')
                )

这应该返回计数的字典VS内容类型ID,相当接近你想要什么。

© www.soinside.com 2019 - 2024. All rights reserved.