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] (Admin view) Cloning from "bulk" doees not work, while it works fine inside of instance editor #333

Closed
flying-sausages opened this issue May 17, 2021 · 2 comments
Labels
bug Something isn't working

Comments

@flying-sausages
Copy link

Describe the bug
With the same exact codebase, I am able to use the make_clone() method as well as making a duplicate of an instance from within the specific instance's "Change" view in the admin panel, but I cannot make a clone from the admin view where i select instances to duplicate, select duplicate from the dropdown, and then press "Go"

To Reproduce

  1. Define the following models:
class Tas(CloneMixin, models.Model):
    """The top level object of the TAS which only holds top-level necessary information"""
    productName = models.CharField(
        max_length=MAX_CHAR_LENGTH, verbose_name="Product Name", unique=True)
    metadata = models.OneToOneField(
        "TasMetadata", on_delete=models.DO_NOTHING, blank=True, null=True, related_name='tas')
    slug = AutoSlugField(populate_from='productName', always_update=True, unique=True, editable=False)
    _clone_m2o_or_o2m_fields = ['diagrams']
    _clone_excluded_fields = ['slug']

    def __str__(self):
        return self.productName

    class Meta:
        verbose_name_plural = "TASes"

class TasMetadata(CloneMixin, models.Model):
    """Separate class to hold information which should be easily editable and versionable about the TAS model"""
    nickname = models.CharField(
        max_length=MAX_CHAR_LENGTH, help_text="Familiar codename")

    predecessor = models.ForeignKey(
        Tas, on_delete=DO_NOTHING, blank=True, null=True, related_name='children', help_text="Optional: The \"parent\" TAS")
    npiPhase = models.ForeignKey(
        NpiPhase, blank=True, null=True, on_delete=SET_NULL, default=None, verbose_name="NPI Phase")

    _clone_m2m_fields = ['npiPhase']

    def __str__(self):
        return f"{self.tas} (a.k.a {self.nickname})"

    class Meta:
        verbose_name = 'TAS Metadata'
        verbose_name_plural = "TAS Metadata"
  1. Add them to the admin panel
@admin.register(Tas)
class TasAdmin(CloneModelAdminMixin, CompareVersionAdmin):
    formfield_overrides = {
        models.JSONField: {'widget': JSONEditorWidget},
    }
    pass

@admin.register(TasMetadata)
class TasMetadataAdmin(CloneModelAdminMixin, CompareVersionAdmin):
    formfield_overrides = {
        models.JSONField: {'widget': JSONEditorWidget},
    }

    def get_queryset(self, request):
        qs = super().get_queryset(request).prefetch_related('tas__metadata')
        return qs
    pass
  1. Go to admin view
  2. Go to the "change" view of all "TAS" objects
  3. Open one object and duplicate it just to demonstrate it works fine
  4. Go back to the change view
  5. Select one object with the checkmark and select "duplicate" in the drop-down
  6. See traceback below

Expected behavior
The duplication should work from bulk view if it works from the single instance editor

Screenshots
N/A

Desktop (please complete the following information):

  • Django version 3.1.7
  • django-clone version 2.5.3

Additional context
This is the error that I get from the bulk view. Let me know if there's anything else I can provide for this.

Environment:


Request Method: POST
Request URL: http://localhost:8000/admin/tas/tas/

Django Version: 3.1.7
Python Version: 3.9.4
Installed Applications:
['django_db_prefix',
 'django_extensions',
 'model_clone',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'tas.apps.TasConfig',
 'rest_framework',
 'debug_toolbar',
 'reversion',
 'reversion_compare',
 'bootstrap4',
 'iommi',
 'mathfilters',
 'django_bootstrap_icons',
 'markdownify.apps.MarkdownifyConfig',
 'django_fastdev',
 'django_json_widget']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware',
 'iommi.middleware']



Traceback (most recent call last):
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/contrib/admin/options.py", line 614, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/contrib/admin/sites.py", line 233, in inner
    return view(request, *args, **kwargs)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/reversion/admin.py", line 230, in changelist_view
    return super().changelist_view(request, context)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/utils/decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1719, in changelist_view
    response = self.response_action(request, queryset=cl.get_queryset(request))
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1402, in response_action
    response = func(self, request, queryset)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/model_clone/admin.py", line 53, in make_clone
    clone = obj.make_clone()
  File "/opt/homebrew/Cellar/[email protected]/3.9.4/Frameworks/Python.framework/Versions/3.9/lib/python3.9/contextlib.py", line 79, in inner
    return func(*args, **kwds)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/model_clone/mixins/clone.py", line 209, in make_clone
    duplicate = self._create_copy_of_instance(self)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/model_clone/mixins/clone.py", line 350, in _create_copy_of_instance
    sub_instance.save()
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/db/models/base.py", line 753, in save
    self.save_base(using=using, force_insert=force_insert,
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/db/models/base.py", line 801, in save_base
    post_save.send(
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/dispatch/dispatcher.py", line 177, in send
    return [
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/dispatch/dispatcher.py", line 178, in <listcomp>
    (receiver, receiver(signal=self, sender=sender, **named))
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/reversion/revisions.py", line 330, in _post_save_receiver
    add_to_revision(instance, model_db=using)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/reversion/revisions.py", line 215, in add_to_revision
    _add_to_revision(obj, db, model_db, True)
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/reversion/revisions.py", line 196, in _add_to_revision
    object_repr=force_str(obj),
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/utils/encoding.py", line 64, in force_str
    s = str(s)
  File "/Users/sausage/Git/Work/webtas/tas/models.py", line 104, in __str__
    return f"{self.tas} (a.k.a {self.nickname})"
  File "/Users/sausage/Git/Work/webtas/.env/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 421, in __get__
    raise self.RelatedObjectDoesNotExist(

Exception Type: RelatedObjectDoesNotExist at /admin/tas/tas/
Exception Value: TasMetadata has no tas.

Again, this works just fine when I do Tas.objects.first().make_clone() or when I run it from the instance editor.

@flying-sausages flying-sausages added the bug Something isn't working label May 17, 2021
@github-actions
Copy link
Contributor

Thanks for reporting this issue.

@jackton1
Copy link
Member

jackton1 commented Jun 19, 2021

@flying-sausages

After running this locally the problem seems to be

    nickname = models.CharField(
        max_length=MAX_CHAR_LENGTH, help_text="Familiar codename")

    predecessor = models.ForeignKey(
        Tas, on_delete=DO_NOTHING, blank=True, null=True, related_name='children', help_text="Optional: The \"parent\" TAS")
    npiPhase = models.ForeignKey(
        NpiPhase, blank=True, null=True, on_delete=SET_NULL, default=None, verbose_name="NPI Phase")

    _clone_m2m_fields = ['npiPhase']

    def __str__(self):
        return f"{self.tas} (a.k.a {self.nickname})"  ## <-- HERE: Change `self.tas` to `self.predecessor` 

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

2 participants