2011-05-04 16 views
21

में डुप्लिकेट निकालें वहाँ निम्न बुनियादी क्वेरी में डुप्लिकेट निकालने के लिए एक सरल तरीका है। क्या आप डुप्लीकेट के बिना इस क्वेरी को करने के लिए मुझे सही वाक्यविन्यास दिखा सकते हैं? धन्यवाद।एक Django क्वेरी

+2

जब कई पंक्तियों के साथ काम कर, कृपया देखें: http://stackoverflow.com/questions/13700200/django-remove-duplicate-objects-where-there -इस-से-एक-फ़ील्ड-टू-तुलना/13700642 # 13700642 –

उत्तर

64

यह क्वेरी आपको डुप्लिकेट नहीं देगी - यानी, यह आपको ईमेल द्वारा आदेशित डेटाबेस में सभी पंक्तियां देगी।

हालांकि, मुझे लगता है कि आपका मतलब यह है कि आपके डेटाबेस में डुप्लिकेट डेटा है। यहां distinct() जोड़ने से मदद नहीं मिलेगी, क्योंकि यदि आपके पास केवल एक फ़ील्ड है, तो आपके पास स्वचालित id फ़ील्ड भी है - इसलिए आईडी + ईमेल का संयोजन अद्वितीय नहीं है।

मान लिया जाये कि आप केवल एक क्षेत्र, email_address, डी-डुप्लीकेट की जरूरत है, तो आप ऐसा कर सकते हैं:

email_list = Email.objects.values_list('email', flat=True).distinct() 

हालांकि, अगर तुम सच में जड़ समस्या को ठीक करना चाहिए, और अपने डेटाबेस से डुप्लिकेट डेटा को हटा दें।

उदाहरण के लिए, ईमेल क्षेत्र डुप्लीकेट ईमेल को हटाने: नाम से

for email in Email.objects.values_list('email', flat=True).distinct(): 
    Email.objects.filter(pk__in=Email.objects.filter(email=email).values_list('id', flat=True)[1:]).delete() 

या किताबें:

for name in Book.objects.values_list('name', flat=True).distinct(): 
    Book.objects.filter(pk__in=Artwork.objects.filter(name=name).values_list('id', flat=True)[3:]).delete() 
+0

ग्रेट सॉल्यूशन। '.values ​​(..) 'का उपयोग करते समय आप इसे kwargs के रूप में भी पास कर सकते हैं। Filter (...)' – vdboor

+0

दूसरे कोड उदाहरण में, हमें ईमेल के सभी डुप्लीकेट हटाने के लिए व्यवहार्य सेट करना चाहिए?एक बार पुनरावृत्ति समाप्त होने के कारण, ईमेल ऑब्जेक्ट्स ईमेल ऑब्जेक्ट्स की पूरी क्वेरीसेट बन जाती है, है ना? – nextdoordoc

3

आप अपने मॉडल के आधार पर distinct() फ़ंक्शन का उपयोग करने में सक्षम हो सकते हैं।

email_list = Emails.objects.values_list('email').order_by('email').distinct() 

जो आप ईमेल के एक आदेश दिया सूची देना चाहिए: यदि आप केवल पुनः प्राप्त करने के लिए एक एकल क्षेत्र मॉडल के रूप में चाहते हैं, आप की तरह कुछ कर सकता है।

0

मैं वास्तव में डेटाबेस से से डुप्लिकेट प्रविष्टियों को दूर करने के बाद, उम्मीद है कि इस मदद करता है इस्तेमाल कोई और।

adds = Address.objects.all() 
d = adds.distinct('latitude', 'longitude') 
for address in adds:  
    if i not in d: 
    address.delete() 
+1

ओआरएम संचालन के आसपास लूप लागू करना आम तौर पर एक बुरा विचार है, क्योंकि यह बहुत अच्छी तरह से स्केल नहीं करता है। इस उदाहरण में, आपके पास कई, कई प्रश्न निष्पादित किए जा रहे हैं। मान लीजिए कि 'जोड़ों' में कई पंक्तियां लौटा दी गई हैं। प्रत्येक पाश में, आप यह देखने के लिए पहली क्वेरी लॉन्च करते हैं कि 'मैं डी में नहीं हूं, और संभावित रूप से प्रभावित' पता 'रिकॉर्ड्स को हटाने के लिए दूसरा। आप पीआरथन लूप के बिना सीधे ओआरएम में ऐसा कुछ कर सकते हैं जैसे: 'address.objects.exclude (pk__in = d.values ​​('pk, flat = True))। (हटाएं)। (आपको इसे ट्विक करने की आवश्यकता हो सकती है - मैंने परीक्षण नहीं किया है)। – BillyBBone

+0

टिप के लिए धन्यवाद –

2
नकल यदि आप एक GROUP_BY और नीचे के रूप में Django में HAVING कर सकते हैं की जाँच के लिए

। हम Django annotations का उपयोग कर रहे हैं।

from django.db.models import Count 
from app.models import Email 

duplicate_emails = Email.objects.values('email').annotate(email_count=Count('email')).filter(email_count__gt=1) 

अब उपरोक्त डेटा के माध्यम से पाशन और पहले एक को छोड़कर अन्य सभी emails को हटाने (या जो कुछ भी आवश्यकता पर निर्भर करता है)।

for data in duplicates_emails: 
    email = data['email'] 
    Email.objects.filter(email=email).order_by('pk')[1:].delete() 
0

तुम भी उपयोग कर सकते हैं set()

email_list = set(Emails.objects.values_list('email', flat=True)) 
संबंधित मुद्दे