Skip to content

[BUG] __duplicate_m2m_fields doesn't work for other db with 'through' attribute #816

@accedx

Description

@accedx

Is there an existing issue for this?

  • I have searched the existing issues

Does this issue exist in the latest version?

  • I'm using the latest release

Describe the bug?

Hello, if model field has 'through' attribute, that code doesn't use source model instance db id

https://github.com/tj-django/django-clone/blob/a401427bddc3d4be267400ce030ea08b66f92f4d/model_clone/mixin.py#L664C24-L664C24

I suggest add 'using' to 'through.objects'
objs = through.objects.using(self._state.db).filter(**{field_name: self.pk})

Or remove this 'if', and leave only code into 'else' branch. 'Else' branch work perfectly for 'through' if is exists.

    for field in fields:
        if hasattr(field, "field"):
            # ManyToManyRel
            field_name = field.field.m2m_reverse_field_name()
            through = field.through
            source = getattr(self, field.get_accessor_name())
            destination = getattr(duplicate, field.get_accessor_name())
        else:
            through = field.remote_field.through
            field_name = field.m2m_field_name()
            source = getattr(self, field.attname)
            destination = getattr(duplicate, field.attname)

        items_clone = []
        for item in source.all():
            if hasattr(item, "make_clone"):
                try:
                    item_clone = item.make_clone(
                        using=using,
                    )
                except IntegrityError:
                    item_clone = item.make_clone(
                        sub_clone=True,
                        using=using,
                    )
            else:
                item_clone = CloneMixin._create_copy_of_instance(
                    item,
                    force=True,
                    sub_clone=True,
                    using=using,
                )
                item_clone.save(using=using)
                items_clone.append(item_clone)

            destination.set(items_clone)

    return duplicate

To Reproduce

class Product(Model, CloneMixin):
    pass

class Catalog(Model, CloneMixin):
    products = ManyToManyField(Product, through='CatalogThrough')

class CatalogThrough(Model):
    catalog = ForeignKey(Catalog)
    product = ForeignKey(Product)

Catalog.objects.using('db-id-1').get(pk=1).make_clone(using=DEFAULT_DB_ALIAS)

What OS are you seeing the problem on?

No response

Expected behavior?

Copy products from 'db-id-1'

Relevant log output

No response

Anything else?

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions