2010-11-26 5 views
14

मैं यह करने के कोशिश कर रहा हूँ लिया गया है:Django: एक प्रश्न अपडेट नहीं कर सकते एक बार एक टुकड़ा

UserLog.objects.filter(user=user).filter(action='message').filter(timestamp__lt=now)[0:5].update(read=True) 

लेकिन मैं इस त्रुटि हो रही है:

Cannot update a query once a slice has been taken. 

(Django 1.2.1 का प्रयोग करके)

मैं क्या गलत कर रहा हूं?

उत्तर

17

त्रुटि स्थिति के रूप में, यदि आप एक टुकड़ा निकाल लेते हैं तो आप QuerySet पर update() पर कॉल नहीं कर सकते हैं।

कारण:

  1. एक टुकड़ा ले रहा है SQL में एक LIMIT बयान के बराबर है।
  2. अद्यतन जारी करने से आपकी क्वेरी UPDATE कथन में बदल जाती है।

आप,

UPDATE ... WHERE ... LIMIT 5

जो संभव नहीं है के बराबर होगा करने के लिए कम से कम मानक SQL साथ नहीं कोशिश कर रहे हैं।

+5

पर बहुत अधिक धन्यवाद के बाद स्लाइसिंग के बाद होता है। मुझे मेरी त्रुटि दिखाई देती है। क्या इसके समाधान की कोई युक्ति है? (पीसी पर लूपिंग और प्रत्येक को अपडेट करने के अलावा?) – xpanta

+0

'अद्यतन ... जहां ... MySQL में LIMIT 1' संभव है। "अद्यतन ... अद्यतन के लिए" ताले से बचने के लिए काफी उपयोगी है। – est

+0

@ आप सही हैं, मैंने थोड़ा जवाब दिया है। ध्यान दें कि OP कभी भी उपयोग किए जाने वाले डेटाबेस के प्रकार का उल्लेख नहीं करता है। –

43

documentation suggests कि निम्नलिखित की तरह कुछ संभव हो सकता है - मैं टुकड़ा करने की क्रिया के बाद यकीन है कि एक आंतरिक QuerySet में सीमित कर जांच नजरअंदाज update() बुला चारों ओर अगर नहीं कर रहा हूँ:

inner_q = UserLog.objects.filter(user=user, 
           action='message', 
           timestamp__lt=now).values('pk')[0:5] 
UserLog.objects.filter(pk__in=inner_q).update(read=True) 

असफल, आप in field lookup इसलिए की तरह इस्तेमाल कर सकते हैं:

ids = UserLog.objects.filter(user=user, 
          action='message', 
          timestamp__lt=now).values_list('pk', flat=True)[0:5] 
UserLog.objects.filter(pk__in=list(ids)).update(read=True) 
+2

पहली विधि मेरे लिए काम किया। दूसरे की कोशिश नहीं की। –

+0

धागा सुरक्षित नहीं है। "चयन करें ... अद्यतन के लिए" – est

+1

का उपयोग करें शायद उन्हें इन्हें "लेनदेन के साथ" रखना चाहिए। ("ब्लॉक। –

1

मैं एक ही गलती हो रही थी या किसी क्वेरीसेट द्वारा लौटाए गए रिकॉर्ड की संख्या को सीमित करने का प्रयास करते समय।

मैंने पाया है कि अगर हम में से एक का उपयोग कर रहे है कि Django के class-based generic views ऐसे ArchiveIndexView के रूप में, हम अभिलेखों की संख्या को सीमित करने के paginate_by = विशेषता का उपयोग कर सकते हैं।

उदाहरण के लिए (views.py में):

from django.views.generic import ArchiveIndexView 
from .models import Entry 

class HomeListView(ArchiveIndexView): 
    """ Blog Homepage """ 
    model = Entry 
    date_field = 'pub_date' 
    template_name = 'appname/home.html' 
    queryset = Entry.objects.filter(
     is_active=True).order_by('-pub_date', 'title') 
    paginate_by = 30 
+1

यह बहुत अच्छा और साफ है, जब तक आप पेजिनेशन नहीं चाहते हैं। मुझे लगता है कि आप यह भी समझ सकते हैं कि आप कोड को अस्पष्ट बना रहे हैं, क्योंकि आप कह रहे हैं कि यह पेजिनेटेड है लेकिन फिर इसे टेम्पलेट में पेजिनेटेड नहीं किया गया है, लेकिन यह अन्य विधियों की तुलना में बहुत तेज़ और आसानी से स्पष्ट है। –

0

आप एक क्वेरीसमूह के परिणामों में से कुछ काट चाहते हैं, आप इसे यह एक और चर के लिए (कॉपी कर सकते हैं एक उथले प्रतिलिपि के लिए पर्याप्त है, जो तेजी से एक गहरी प्रतिलिपि से, क्योंकि यह सिर्फ मूल वस्तुओं के लिए संदर्भ का उपयोग करता है।)

import copy 

queryset = Mytable.objects.all() 
pieceOfQuery = copy.copy(queryset) 
pieceOfQuery = pieceOfQuery[:10] 

इस शिकायत से Django रखेंगे अगर आप पर अपने टा एक order_by फिल्टर है ब्ली, चूंकि यह मुख्य क्वेरीसेट ऑब्जेक्ट

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