Question

J'ai une table avec un IntegerField ( hit_count ) et lorsqu'une page est visitée (par exemple, http: // site / page / 3 ) Je souhaite que la colonne hit_count de la base de données de l'enregistrement 3 soit incrémentée de 1.

La requête devrait ressembler à:

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

Puis-je faire cela avec les conventions standard du modèle Django? Ou devrais-je simplement écrire la requête à la main?

Était-ce utile?

La solution

Si vous utilisez Django 1.1+, utilisez simplement expressions F :

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

Ceci effectuera une requête de base de données atomique unique.

Comme le dit gerdemb, vous devriez envisager de le placer dans un middleware pour le rendre facilement réutilisable, de manière à ne pas encombrer tous vos points de vue.

Autres conseils

Comme le dit gerdemb, vous devriez l’écrire dans un middleware pour le rendre vraiment réutilisable. Ou (plus simple) écrivez un décorateur de fonctions. En fait, il existe des adaptateurs pour utiliser un middleware en tant que décorateur et vice-versa.

Toutefois, si vous êtes préoccupé par les performances et que vous souhaitez conserver les requêtes de base de données par page trop basses, vous pouvez utiliser l'opération d'incrémentation atomique de memcached. bien sûr, dans ce cas, vous devez prendre soin de vous-même.

Les conventions de modèle ne seront pas atomiques; écrivez-le à la main:

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

Je commencerai par examiner la documentation de middleware . Le commentaire d'Ignacio sur le manque de transactions atomiques est vrai, mais c'est un problème avec tout le framework Django. À moins que vous ne craigniez d'avoir un compteur précis à 100%, je ne m'en inquiéterais pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top