Paste object data into admin form

Need help. I have an object that I add using the standard administration form by link /admin/tasklist/task/add/

model.py

class Task(models.Model):
    name = models.CharField("Name", max_length=100)
    discr = models.CharField("Discription", max_length=255)
    date = models.DateField("Date")
    status = models.IntegerField("Status", default=2)

    def __str__(self):
        return self.name

    def natural_key(self):
        return (self.name)

    class Meta:
        db_table = 'tasks'
        verbose_name = 'Task'
        verbose_name_plural = 'Tasks'

I want to be able to copy an object after making edits from the same admin form. I need that when clicking on the link /admin/tasklist/task/1/copy, the form for adding an object opens, and data from object 1 is inserted into the status and date fields.

Maybe I need to create one Custom Admin Actions for this?

Rather than creating custom admin for this , why not you just create 2 views , where in view 1-> you insert object and view2 ->you copy object

It is doable, although it is not straightforward. We can define a mixin that adds a /<path:object_id>/copy/ path, and if that is the case, return as object to edit the same object, except where we remove the primary key, like:

from functools import update_wrapper

from django.contrib import admin


class DuplicateAdminMixin:
    def copy_view(self, request, object_id, extra_context=None):
        request.copying = True
        return self.change_view(request, object_id, extra_context)

    def get_object(self, request, object_id, from_field=None):
        object = super().get_object(request, object_id, from_field=from_field)
        if getattr(request, 'copying', False):
            object.pk = None
        return object

    def get_urls(self):
        urls = super().get_urls()
        info = self.opts.app_label, self.opts.model_name
        from django.urls import path

        def wrap(view):
            def wrapper(*args, **kwargs):
                return self.admin_site.admin_view(view)(*args, **kwargs)

            wrapper.model_admin = self
            return update_wrapper(wrapper, view)

        custom_urls = [
            path(
                '<path:object_id>/copy/',
                wrap(self.copy_view),
                name='%s_%s_copy' % info,
            ),
        ]
        return custom_urls + urls

then you can mix in the DuplicateAdminMixin in your ModelAdmin:

class TaskAdmin(DuplicateAdminMixin, admin.ModelAdmin):
    # …

then if you have an object with primary key 1, you can thus go to the /admin/app_label/model_name/1/copy/ to obtain a form with the data of that item, but it will make a copy if you save the object.

Data from related models is not copied.

Вернуться на верх