Python 增加Django中的页面命中计数

Python 增加Django中的页面命中计数,python,django,django-models,Python,Django,Django Models,我有一个带有IntegerField(hit\u count)的表,在访问页面时(例如,http://site/page/3)我希望数据库中记录ID 3的命中计数列增加1 查询应类似于: 更新表集命中计数=命中计数+1,其中id=3 我可以用标准的Django模型约定来实现这一点吗?还是我应该手工编写查询?模型约定不会是原子的;手写: BEGIN SELECT * FROM table WHERE id=3 FOR UPDATE UPDATE table SET hit_count=hit_c

我有一个带有
IntegerField
hit\u count
)的表,在访问页面时(例如,
http://site/page/3
)我希望数据库中记录ID 3的
命中计数
列增加1

查询应类似于:

更新表集命中计数=命中计数+1,其中id=3

我可以用标准的Django模型约定来实现这一点吗?还是我应该手工编写查询?

模型约定不会是原子的;手写:

BEGIN
SELECT * FROM table WHERE id=3 FOR UPDATE
UPDATE table SET hit_count=hit_count+1 WHERE id=3
COMMIT

首先,我将查看有关的文档。Ignacio关于缺少原子事务的评论是正确的,但这是整个Django框架的一个问题。除非你担心有一个100%准确的计数器,否则我不会担心它。

正如gerdemb所说,你应该把它写进一个中间件,使它真正可重用。或者(更简单)编写一个函数修饰符。事实上,有一些适配器将中间件用作装饰器,反之亦然


但是,如果您担心性能,并且希望将每页的DB查询数保持在较低水平,则可以使用memcached的原子增量操作。当然,在这种情况下,您必须自己处理持久性。

如果您使用Django 1.1+,只需使用:

这将执行单个原子数据库查询


正如gerdemb所说,你应该考虑把它放在一个中间件中,以便它可以重复使用,这样它就不会使你的所有视图混乱不堪。



如果您提供模型本身,它会有所帮助。Django的ORM的可能副本支持此查询(在trunk中,很快将在v1.1中)-您不需要手动编写。这是一个“整个Django框架的问题”吗?您可以使用TransactionMiddleware对每个请求进行原子事务,或者使用django.db.transaction中的函数获得更细粒度的控制。确保您可以拥有事务,但默认情况下不会启用它们。如果您使用内置的Django admin构建一个简单的CRUD应用程序,您将有竞争条件。就连Django文档中的教程也有这样的问题。你的措辞让它听起来像是一个不可避免的问题,这当然会误导那些可能没有你那么了解Django的人。为了获得良好的性能,memcached解决方案是目前为止最好的,但它更复杂。+1:谢谢-本想链接到那个,但忘了。我将添加它。我认为您需要的是
MyModel.objects.get(id=…)
,而不是
filter
;如果我们知道它是一行,为什么不说清楚呢?@Jared,因为.get()并不懒惰(它实际上是查询数据库)。这就是为什么单个模型对象没有.update()方法;查询完成后,只需使用.save()。但是你失去了原子性,这就是这里的重点。原子更新的.update()方法只在QuerySet上可用,并且只可能是因为它们是惰性的。哦,这很有趣。谢谢
from django.db.models import F
...
MyModel.objects.filter(id=...).update(hit_count=F('hit_count')+1)