2009-03-07 19 views
16

में मारो गणना मैं एक IntegerField (hit_count) के साथ एक मेज है, और जब एक पृष्ठ को देखे जाने (उदाहरण के लिए, http://site/page/3) मैं रिकॉर्ड आईडी डेटाबेस में 3 की hit_count स्तंभ 1.वृद्धि पृष्ठ Django

से बढ़ाने के लिए चाहते हैं

क्वेरी होना चाहिए की तरह:

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

मैं मानक Django मॉडल सम्मेलनों के साथ ऐसा कर सकते हैं? या क्या मुझे सिर्फ हाथ से पूछना चाहिए?

+0

यदि आप मॉडल को स्वयं प्रदान करते हैं तो यह मदद करता है। –

+0

संभावित डुप्लिकेट [डीजेंगो में एक काउंटर की परमाणु वृद्धि] (http://stackoverflow.com/questions/1598932/atomic-increment-of-a-counter-in-django) –

उत्तर

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

+1: http://docs.djangoproject.com/en/dev/topics/db/queries/#filters-can-reference-fields-on-the-model –

+0

धन्यवाद - इसका लिंक करने के लिए मतलब था लेकिन भूल गया। मैं इसे जोड़ दूंगा। –

+1

मुझे लगता है कि आप चाहते हैं कि 'MyModel.objects.get (id = ...) '' फ़िल्टर' के विपरीत है; अगर हम जानते हैं कि यह एक पंक्ति है, तो इसे स्पष्ट क्यों न करें? –

0

मॉडल सम्मेलन परमाणु नहीं होंगे; हाथ से लिखने:

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

Django के ORM में इस क्वेरी के लिए समर्थन है ट्रंक, और जल्द ही v1.1) - आपको इसे हाथ से लिखने की आवश्यकता नहीं है। –

0

मैं middleware के लिए दस्तावेज़ को देखकर शुरू करेंगे। परमाणु लेनदेन की कमी के बारे में Ignacio की टिप्पणी सच है, लेकिन यह पूरे Django ढांचे के साथ एक समस्या है। जब तक आप 100% सटीक काउंटर रखने के बारे में चिंतित न हों, मैं इसके बारे में चिंता नहीं करता।

+0

यह कैसे "पूरे Django ढांचे के साथ समस्या है?" आप TransactionMiddleware के साथ प्रति अनुरोध परमाणु लेनदेन कर सकते हैं, या django.db.transaction में कार्यों के साथ बेहतर अनाज नियंत्रण प्राप्त कर सकते हैं। –

+0

निश्चित रूप से आप लेनदेन कर सकते हैं, लेकिन वे डिफ़ॉल्ट रूप से सक्षम नहीं हैं। यदि आप अंतर्निहित Django व्यवस्थापक का उपयोग करके एक सरल सीआरयूडी अनुप्रयोग बनाते हैं तो आपको दौड़ की स्थिति होगी। यहां तक ​​कि Django दस्तावेज़ीकरण में ट्यूटोरियल भी इस तरह की समस्या है। – user27478

+0

जिस तरह से आपने इसे phrased किया है, यह एक अपरिहार्य समस्या की तरह लगता है, जो निश्चित रूप से किसी ऐसे व्यक्ति के लिए भ्रामक है जो आपके जैसे Django के बारे में ज्यादा नहीं जानता है। – Jordan

4

जैसा कि gerdemb कहते हैं, आपको इसे वास्तव में पुन: प्रयोज्य बनाने के लिए इसे एक मिडलवेयर में लिखना चाहिए। या (सरल) एक समारोह सजावट लिखो। वास्तव में, एक मिडलवेयर का उपयोग एक सजावटी और उपाध्यक्ष के रूप में करने के लिए एडाप्टर हैं।

लेकिन यदि आप प्रदर्शन के बारे में चिंतित हैं और प्रति पृष्ठ डीबी क्वेरी को कम रखना चाहते हैं, तो आप memcached के परमाणु वृद्धि ऑपरेशन का उपयोग कर सकते हैं। बेशक, इस मामले में, आपको दृढ़ता का ख्याल रखना होगा।

+0

अच्छे प्रदर्शन के लिए, memcached समाधान अब तक सबसे अच्छा है, लेकिन यह अधिक जटिल है। –

संबंधित मुद्दे