2010-06-15 21 views
5

में ऑब्जेक्ट्स के लिए ऑर्डर विशेषता अद्यतन करें मेरे पास ऑब्जेक्ट ऑर्डर करने की अनुमति देने के लिए मेरे मॉडल पर एक विशेषता है। मुझे सूची के आधार पर तत्व के क्रम को अपडेट करना होगा, जिसमें ऑब्जेक्ट की आईडी नए ऑर्डर में हो; अभी मैं पूरी क्वेरीसेट पर पुनरावृत्ति कर रहा हूं और दूसरे के बाद एक ऑब्जेक्ट्स सेट कर रहा हूं। संपूर्ण क्वेरीसेट के साथ ऐसा करने का सबसे आसान/तेज़ तरीका क्या होगा?Django: एक क्वेरीसेट

def update_ordering(model, order): 
    """ order is in the form [id,id,id,id] for example: [8,4,5,1,3] """ 
    id_to_order = dict((order[i], i) for i in range(len(order))) 
    for x in model.objects.all(): 
     x.order = id_to_order[x.id] 
     x.save() 

उत्तर

4

यह एक एकल क्वेरीसमूह आपरेशन में नहीं किया जा सकता। जहां तक ​​मुझे पता है कि यह कच्चे एसक्यूएल के साथ एक प्रश्न में भी नहीं किया जा सकता है। तो आपको हमेशा उस ऑब्जेक्ट के लिए अपडेट कॉल की आवश्यकता होगी जिसे अपडेट किया जाना है। तो आपके और कॉलिन एंडरसन के दोनों समाधान आपके विवरण के लिए काफी अनुकूल लगते हैं।

हालांकि, आपका उपयोग केस क्या है? क्या वास्तव में पूरी सूची हर बार बदल जाएगी? ज्यादातर स्थितियों में यह बहुत ही असंभव लगता है। मैं कुछ अलग दृष्टिकोण देख सकता हूं।

आपको क्षेत्र को बचाने के आप की तरह कहते हैं, लेकिन आप सूची के लिए एक अंतर उत्पन्न: डीईएफ़

update_ordering(model, order): 
    """ order is in the form [id,id,id,id] for example: [8,4,5,1,3] """ 
    original_order = model.objects.value_list('id', flat=True).order_by('order') 
    order = filter(lambda x: x[1]!=x[2], zip(xrange(len(order)), order, original_order)) 
    for i in order: 
     model.objects.filter(id=i[1]).update(order=i[0]) 

एक और दृष्टिकोण, आप क्या कर रहे हैं एक आंशिक अद्यतन करने के लिए है पर निर्भर करता है (उदाहरण के लिए का उपयोग कर AJAX) यदि संभव हो, तो पूरे पुन: आदेशित सेट को अपडेट करने के बजाय, बस प्रत्येक अपडेट को अलग से अपडेट करें। यह अक्सर कुल भार में वृद्धि करेगा, लेकिन समय के साथ इसे और अधिक फैलाएगा। उदाहरण के लिए 5 वें तत्व चरण-दर-चरण 2 स्थानांतरित करने के लिए ले जाएं, यह 3 स्वैप पेश करेगा: (5,4); (4,3); (3,2)। 6 अपडेट में परिणाम, जबकि सभी में एक-बार दृष्टिकोण के साथ केवल 4 की आवश्यकता होगी। लेकिन छोटे ऑपरेशन समय के साथ फैल जाएगा।

1

अगर यह इस एक क्वेरी का उपयोग करना संभव है मैं नहीं जानता, लेकिन इस किसी भी मामले में और अधिक कुशल है:

def update_ordering(model, order): 
    """ order is in the form [id,id,id,id] for example: [8,4,5,1,3] """ 
    for id in model.objects.values_list('id', flat=True): 
     model.objects.filter(id=id).update(order=order.index(id)) 
+0

मान लीजिए कि यह केवल सभी आइटम प्राप्त करने के लिए डीबी को मारने से बचाता है (सभी वस्तुओं को अपडेट किया जाना चाहिए, इसलिए आपका समाधान उन सभी पर भी पुनरावृत्त होता है)। –

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