Счетчик приращений страниц в Django - PullRequest
16 голосов
/ 08 марта 2009

У меня есть таблица с IntegerField (hit_count), и при посещении страницы (например, http://site/page/3) я хочу, чтобы столбец с идентификатором 3 hit_count в базе данных увеличивался на 1.

Запрос должен выглядеть так:

update table set hit_count = hit_count + 1 where id = 3

Могу ли я сделать это со стандартными соглашениями по модели Django? Или мне просто написать запрос от руки?

Ответы [ 4 ]

31 голосов
/ 08 марта 2009

Если вы используете Django 1.1+, просто используйте F выражений :

from django.db.models import F
...
MyModel.objects.filter(id=...).update(hit_count=F('hit_count')+1)

Это выполнит один атомарный запрос к базе данных.

Как говорит gerdemb, вам следует подумать о том, чтобы поместить это в промежуточное ПО, чтобы его было легко использовать повторно, чтобы оно не загромождало все ваши взгляды.


4 голосов
/ 08 марта 2009

Как говорит gerdemb, вы должны записать его в промежуточное программное обеспечение, чтобы сделать его действительно многоразовым. Или (проще) написать функцию декоратора. На самом деле есть адаптеры для использования промежуточного программного обеспечения в качестве декоратора и наоборот.

Но если вы беспокоитесь о производительности и хотите, чтобы количество запросов к БД на страницу было низким, вы можете использовать атомарную операцию приращения memcached. конечно, в этом случае вы должны позаботиться о настойчивости самостоятельно.

0 голосов
/ 08 марта 2009

Я бы начал с просмотра документации по middleware . Комментарий Игнасио об отсутствии атомарных транзакций верен, но это проблема всей платформы Django. Если бы вы не беспокоились о наличии 100% точного счетчика, я бы об этом не беспокоился.

0 голосов
/ 08 марта 2009

Типовые соглашения не будут атомарными; напишите это от руки:

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