Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
3 tasks done
accedx opened this issue Jul 24, 2023 · 0 comments
Open
3 tasks done
Labels
bug Something isn't working

Comments

@accedx
Copy link

accedx commented Jul 24, 2023

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
@accedx accedx added the bug Something isn't working label Jul 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant