Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Replace duplicate objects with the original
from django.db import transaction
from django.db.models.deletion import Collector
from django.db.models.fields.related import ForeignKey, ManyToManyField, OneToOneField
duplicates = []
items = {}
client = Client.objects.get(name='Demo')
for c in Company.objects.filter(active=True, client=client):
company_name = c.name
if c.id in duplicates:
continue
else:
other_companies = Company.objects.filter(client=client, active=True, name=company_name).exclude(id=c.id)
if other_companies.exists():
ids = [x.id for x in other_companies]
items[c.id] = ids
duplicates += ids
black_list = ['Company_company_owners']
with transaction.atomic():
for k, v in items.iteritems():
org = Company.objects.get(id=k)
for s_v in v:
dup = Company.objects.get(id=s_v)
collector = Collector(using='default')
collector.collect([dup])
for model, instance in collector.instances_with_model():
model_name = model.__name__
if model_name not in black_list:
print dup.id
fields_with_foreign = model._meta.fields
for f in fields_with_foreign:
if isinstance(f, ForeignKey) or isinstance(f, OneToOneField):
f_name = f.rel.field.attname
if f.rel.to is org.__class__:
print 'Foreign Key is setting %s to %s of instance %s, %s' % (f_name, org.id, instance, model)
setattr(instance, f.rel.field.attname, org.id)
many_to_many_fields = model._meta.many_to_many
for f in many_to_many_fields:
f_name = f.rel.field.attname
if f.rel.to is org.__class__:
print 'ManytoMany Key is setting %s to %s from %s of instance %s, %s' % (f_name, org.id, dup.id, instance, model)
instance.__getattribute__(f_name).remove(dup)
instance.__getattribute__(f_name).add(org)
instance.save()
dup.active = False
dup.save()
print "Duplicate %s set to deactivate" % dup.id
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment