यह यहां करने का एक मूलभूत तरीका है। मान लें कि आपके पास मौजूद डेटा की मात्रा बहुत बड़ी नहीं है, यह ठीक से काम करेगी। आप get_queryset
फ़ंक्शन को ओवरराइड करके और केवल फ़िल्टर किए जाने पर अपने विचारों में इसका उपयोग कर सकते हैं। या यदि आप इसे हर जगह इस्तेमाल करने की योजना बनाते हैं तो आप इसे अपनी कक्षा पर एक स्थैतिक विधि के रूप में उपयोग कर सकते हैं।
values = MyClass.objects.order_by('-created_ts').all()
filtered = []
existing = []
for value in values:
if value.my_integer not in existing:
existing.append(value.my_integer)
filtered.append(value)
चूंकि सूची सबसे हाल ही में आदेश दिया गया है, इसलिए वे उस पूर्णांक के लिए पहले पहले में जोड़े जाएंगे। मैंने इसके साथ कुछ बुनियादी परीक्षण किया, लेकिन इतना नहीं है कि वहां कोई दोष या दो हो सकता है। स्क्लाइट के साथ परीक्षण किया गया।
संपादित
यहाँ एक बहुत तेजी से संस्करण है।
def iter_tools():
import itertools
qs = MyClass.objects.all()
filtered = []
group_by = itertools.groupby(qs, lambda x: x.my_integer)
for x in group_by:
filtered.append(sorted(x[1], key=lambda x: x.created_ts, reverse=True)[0])
return filtered
अनिवार्य रूप से जिस तरह से यह काम कर रहा है अपने डाटाबेस से अपने वस्तुओं के सभी हो रही है, पूर्णांक द्वारा उन्हें समूहीकरण, तो टाइमस्टैम्प के आधार पर प्रत्येक समूह छंटाई और बस प्रत्येक समूह से पहले एक हो रही। इसे और भी तेज़ करना मेरे कौशल से परे है लेकिन मुझे यकीन है कि कुछ तरीके हैं।
In[]: timeit.timeit(manual, number=1500)
Out[]: 0.5577559471130371
In[]: timeit.timeit(iter_tools, number=1500)
Out[]: 0.39012885093688965
-----------------------------------------------
In[]: timeit.timeit(manual, number=5000)
Out[]: 1.770777940750122
In[]: timeit.timeit(iter_tools, number=5000)
Out[]: 1.2411231994628906
संपादित करें 2: मैं डेटाबेस के लिए 60000 ऑब्जेक्ट का निर्माण कुछ के साथ इसे आज़माने के लिए
यहाँ बनाम DB में 6 केवल तरह प्रविष्टियों के साथ पहले भी इस एक के timeit
है डेटा। मैंने django-fixtureless के साथ डेटा जेनरेट किया है, इसलिए पूर्णांक पूरी तरह यादृच्छिक हैं और उनमें से सभी पर टाइमस्टैम्प प्रत्येक ऑब्जेक्ट के लिए एक नया datetime.now()
है।
In[]: timeit.timeit(manual, number=1)
Out[]: 11.946185827255249
In[]: timeit.timeit(iter_tools, number=1)
Out[]: 0.7811920642852783
In[]: timeit.timeit(iter_tools, number=100)
Out[]: 77.93837308883667
In[]: MyClass.objects.all().count()
Out[]: 60000
डीबी के बारे में एक नोट: उपरोक्त उदाहरण में मैं सिर्फ अपनी स्थानीय मशीन पर sqlite3 का उपयोग कर रहा था। मैं अभी एक वीएम के रूप में एक त्वरित छोटा mysql सर्वर सेटअप और एक बेहतर गति परिणाम प्राप्त किया।
In[16]: MyClass.objects.all().count()
Out[16]: 60000
In[17]: timeit.timeit(iter_tools, number=100)
Out[17]: 49.636733055114746
In[18]: timeit.timeit(iter_tools, number=1)
Out[18]: 0.4923059940338135
किसी भी तरह से, आपको वही वस्तुएं वापस मिलती हैं।यदि प्रदर्शन एक मुद्दा है तो मैं या तो itertools एक या एक कस्टम एसक्यूएल क्वेरी का उपयोग करने की सिफारिश करता हूं।
'नवीनतम' का मतलब केवल एक है। – Gocht
"my_integer के प्रत्येक अद्वितीय मान के लिए नवीनतम बनाए गए_ट्स"। इसका मतलब है कि एक से अधिक। –
@ सक्बिबाली आपका प्रश्न बताता है "मैं 'माइक्लास' [...]" के उदाहरणों को पुनर्प्राप्त करना चाहता हूं, लेकिन आपने एक ऐसा उत्तर स्वीकार कर लिया है जो 'MyClass' के उदाहरणों को पुनर्प्राप्त नहीं करता है। यह शब्दकोश देता है। आप भी [टिप्पणी] (http://stackoverflow.com/questions/32359954/how-to-make-django-queryset-that-selects-records-with-max-value-within-a-group#comment52598332_32361355) दूसरे पर जवाब दें कि आप कक्षा के उदाहरण चाहते हैं। – Louis