(primary_object, alias_objects=[], keep_old=False)
return primary_object
Use this function to merge model objects (i.e. Users, Organizations, Polls,
    etc.) and migrate all of the related fields from the alias objects to the
    primary object.

    Usage:
    from django.contrib.auth.models import User
    primary_user = User.objects.get(email='good_email@example.com')
    duplicate_user = User.objects.get(email='good_email+duplicate@example.com')
    merge_model_objects(primary_user, duplicate_user)
Use this function to merge model objects (i.e. Users, Organizations, Polls,
    etc.) and migrate all of the related fields from the alias objects to the
    primary object.
Use this function to merge model objects ( i . e . Users Organizations Polls etc . ) and migrate all of the related fields from the alias objects to the primary object .
def merge_model_objects(primary_object, alias_objects=[], keep_old=False):
    """
    Use this function to merge model objects (i.e. Users, Organizations, Polls,
    etc.) and migrate all of the related fields from the alias objects to the
    primary object.

    Usage:
    from django.contrib.auth.models import User
    primary_user = User.objects.get(email='good_email@example.com')
    duplicate_user = User.objects.get(email='good_email+duplicate@example.com')
    merge_model_objects(primary_user, duplicate_user)
    """
    if not isinstance(alias_objects, list):
        alias_objects = [alias_objects]

    # check that all aliases are the same class as primary one and that
    # they are subclass of model
    primary_class = primary_object.__class__

    if not issubclass(primary_class, Model):
        raise TypeError("Only django.db.models.Model subclasses can be merged")

    for alias_object in alias_objects:
        if not isinstance(alias_object, primary_class):
            raise TypeError("Only models of same class can be merged")

    # Get a list of all GenericForeignKeys in all models
    # TODO: this is a bit of a hack, since the generics framework should
    # provide a similar method to the ForeignKey field for accessing the
    # generic related fields.
    generic_fields = []
    for model in apps.get_models():
        fields = filter(
            lambda x: isinstance(x[1], GenericForeignKey), model.__dict__.items()
        )
        for field_name, field in fields:
            generic_fields.append(field)

    blank_local_fields = set(
        [
            field.attname
            for field in primary_object._meta.local_fields
            if getattr(primary_object, field.attname) in [None, ""]
        ]
    )

    # Loop through all alias objects and migrate their data to
    # the primary object.
    for alias_object in alias_objects:
        # Migrate all foreign key references from alias object to
        # primary object.
        for related_object in _get_all_related_objects(alias_object):
            # The variable name on the alias_object model.
            alias_varname = related_object.get_accessor_name()
            # The variable name on the related model.
            obj_varname = related_object.field.name
            related_objects = getattr(alias_object, alias_varname)
            for obj in related_objects.all():
                setattr(obj, obj_varname, primary_object)
                reassigned(obj, primary_object)
                obj.save()

        # Migrate all many to many references from alias object to
        # primary object.
        related = _get_all_related_many_to_many_objects(alias_object)
        for related_many_object in related:
            alias_varname = related_many_object.get_accessor_name()
            obj_varname = related_many_object.field.name

            if alias_varname is not None:
                # standard case
                related_many_objects = getattr(alias_object, alias_varname).all()
            else:
                # special case, symmetrical relation, no reverse accessor
                related_many_objects = getattr(alias_object, obj_varname).all()
            for obj in related_many_objects.all():
                getattr(obj, obj_varname).remove(alias_object)
                reassigned(obj, primary_object)
                getattr(obj, obj_varname).add(primary_object)

        # Migrate all generic foreign key references from alias
        # object to primary object.
        for field in generic_fields:
            filter_kwargs = {}
            filter_kwargs[field.fk_field] = alias_object._get_pk_val()
            filter_kwargs[field.ct_field] = field.get_content_type(alias_object)
            related = field.model.objects.filter(**filter_kwargs)
            for generic_related_object in related:
                setattr(generic_related_object, field.name, primary_object)
                reassigned(generic_related_object, primary_object)
                try:
                    # execute save in a savepoint, so we can resume in the
                    # transaction
                    with transaction.atomic():
                        generic_related_object.save()
                except IntegrityError as ie:
                    if ie.__cause__.pgcode == PG_UNIQUE_VIOLATION:
                        merge(generic_related_object, primary_object)

        # Try to fill all missing values in primary object by
        # values of duplicates
        filled_up = set()
        for field_name in blank_local_fields:
            val = getattr(alias_object, field_name)
            if val not in [None, ""]:
                setattr(primary_object, field_name, val)
                filled_up.add(field_name)
        blank_local_fields -= filled_up

        if not keep_old:
            before_delete(alias_object, primary_object)
            alias_object.delete()
    primary_object.save()
    return primary_object
def merge_model_objects ( primary_object , alias_objects = [ ] , keep_old = False ) : if not isinstance ( alias_objects , list ) : alias_objects = [ alias_objects ] # check that all aliases are the same class as primary one and that # they are subclass of model primary_class = primary_object . __class__ if not issubclass ( primary_class , Model ) : raise TypeError ( "Only django.db.models.Model subclasses can be merged" ) for alias_object in alias_objects : if not isinstance ( alias_object , primary_class ) : raise TypeError ( "Only models of same class can be merged" ) # Get a list of all GenericForeignKeys in all models # TODO: this is a bit of a hack, since the generics framework should # provide a similar method to the ForeignKey field for accessing the # generic related fields. generic_fields = [ ] for model in apps . get_models ( ) : fields = filter ( lambda x : isinstance ( x [ 1 ] , GenericForeignKey ) , model . __dict__ . items ( ) ) for field_name , field in fields : generic_fields . append ( field ) blank_local_fields = set ( [ field . attname for field in primary_object . _meta . local_fields if getattr ( primary_object , field . attname ) in [ None , "" ] ] ) # Loop through all alias objects and migrate their data to # the primary object. for alias_object in alias_objects : # Migrate all foreign key references from alias object to # primary object. for related_object in _get_all_related_objects ( alias_object ) : # The variable name on the alias_object model. alias_varname = related_object . get_accessor_name ( ) # The variable name on the related model. obj_varname = related_object . field . name related_objects = getattr ( alias_object , alias_varname ) for obj in related_objects . all ( ) : setattr ( obj , obj_varname , primary_object ) reassigned ( obj , primary_object ) obj . save ( ) # Migrate all many to many references from alias object to # primary object. related = _get_all_related_many_to_many_objects ( alias_object ) for related_many_object in related : alias_varname = related_many_object . get_accessor_name ( ) obj_varname = related_many_object . field . name if alias_varname is not None : # standard case related_many_objects = getattr ( alias_object , alias_varname ) . all ( ) else : # special case, symmetrical relation, no reverse accessor related_many_objects = getattr ( alias_object , obj_varname ) . all ( ) for obj in related_many_objects . all ( ) : getattr ( obj , obj_varname ) . remove ( alias_object ) reassigned ( obj , primary_object ) getattr ( obj , obj_varname ) . add ( primary_object ) # Migrate all generic foreign key references from alias # object to primary object. for field in generic_fields : filter_kwargs = { } filter_kwargs [ field . fk_field ] = alias_object . _get_pk_val ( ) filter_kwargs [ field . ct_field ] = field . get_content_type ( alias_object ) related = field . model . objects . filter ( * * filter_kwargs ) for generic_related_object in related : setattr ( generic_related_object , field . name , primary_object ) reassigned ( generic_related_object , primary_object ) try : # execute save in a savepoint, so we can resume in the # transaction with transaction . atomic ( ) : generic_related_object . save ( ) except IntegrityError as ie : if ie . __cause__ . pgcode == PG_UNIQUE_VIOLATION : merge ( generic_related_object , primary_object ) # Try to fill all missing values in primary object by # values of duplicates filled_up = set ( ) for field_name in blank_local_fields : val = getattr ( alias_object , field_name ) if val not in [ None , "" ] : setattr ( primary_object , field_name , val ) filled_up . add ( field_name ) blank_local_fields -= filled_up if not keep_old : before_delete ( alias_object , primary_object ) alias_object . delete ( ) primary_object . save ( ) return primary_object