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