我有一张包含IntegerField
(hit_count
)的表格,当访问某个页面时(例如,http://site/page/3
)我想要记录ID 3的hit_count
列数据库增加1。
查询应该是:
update table set hit_count = hit_count + 1 where id = 3
我可以使用标准的Django模型约定吗?或者我应该手动编写查询?
答案 0 :(得分:31)
如果你使用Django 1.1+,只需使用F expressions:
from django.db.models import F
...
MyModel.objects.filter(id=...).update(hit_count=F('hit_count')+1)
这将执行单个原子数据库查询。
正如gerdemb所说,你应该考虑把它放在一个中间件中,以便它可以轻松重复使用,这样就不会使你的所有观点变得混乱。
答案 1 :(得分:4)
正如gerdemb所说,您应该将其写入中间件,以使其真正可重用。或者(更简单)编写一个函数装饰器。实际上,有些适配器可以将中间件用作装饰器而反之亦然。
但是如果您担心性能并且希望每页的数据库查询保持较低,则可以使用memcached的原子增量操作。当然,在这种情况下,你必须自己照顾持久性。
答案 2 :(得分:0)
模型约定不是原子的;手写:
BEGIN
SELECT * FROM table WHERE id=3 FOR UPDATE
UPDATE table SET hit_count=hit_count+1 WHERE id=3
COMMIT
答案 3 :(得分:0)
我首先看一下middleware的文档。 Ignacio关于缺乏原子事务的评论是正确的,但这是整个Django框架的一个问题。除非你担心100%准确的计数器,否则我不担心。