mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-06-02 21:39:23 +00:00
51 lines
2 KiB
Python
51 lines
2 KiB
Python
|
from django.db.models import ManyToManyField
|
|||
|
|
|||
|
|
|||
|
def update_related(canonical, obj):
|
|||
|
"""update all the models with fk to the object being removed"""
|
|||
|
# move related models to canonical
|
|||
|
related_models = [
|
|||
|
(r.remote_field.name, r.related_model) for r in canonical._meta.related_objects
|
|||
|
]
|
|||
|
for (related_field, related_model) in related_models:
|
|||
|
# Skip the ManyToMany fields that aren’t auto-created. These
|
|||
|
# should have a corresponding OneToMany field in the model for
|
|||
|
# the linking table anyway. If we update it through that model
|
|||
|
# instead then we won’t lose the extra fields in the linking
|
|||
|
# table.
|
|||
|
related_field_obj = related_model._meta.get_field(related_field)
|
|||
|
if isinstance(related_field_obj, ManyToManyField):
|
|||
|
through = related_field_obj.remote_field.through
|
|||
|
if not through._meta.auto_created:
|
|||
|
continue
|
|||
|
related_objs = related_model.objects.filter(**{related_field: obj})
|
|||
|
for related_obj in related_objs:
|
|||
|
print("replacing in", related_model.__name__, related_field, related_obj.id)
|
|||
|
try:
|
|||
|
setattr(related_obj, related_field, canonical)
|
|||
|
related_obj.save()
|
|||
|
except TypeError:
|
|||
|
getattr(related_obj, related_field).add(canonical)
|
|||
|
getattr(related_obj, related_field).remove(obj)
|
|||
|
|
|||
|
|
|||
|
def copy_data(canonical, obj):
|
|||
|
"""try to get the most data possible"""
|
|||
|
for data_field in obj._meta.get_fields():
|
|||
|
if not hasattr(data_field, "activitypub_field"):
|
|||
|
continue
|
|||
|
data_value = getattr(obj, data_field.name)
|
|||
|
if not data_value:
|
|||
|
continue
|
|||
|
if not getattr(canonical, data_field.name):
|
|||
|
print("setting data field", data_field.name, data_value)
|
|||
|
setattr(canonical, data_field.name, data_value)
|
|||
|
canonical.save()
|
|||
|
|
|||
|
|
|||
|
def merge_objects(canonical, obj):
|
|||
|
copy_data(canonical, obj)
|
|||
|
update_related(canonical, obj)
|
|||
|
# remove the outdated entry
|
|||
|
obj.delete()
|