Skip to main content

Create a clone of a django model instance.

Project description

django-clone

Create copies of a model instance with explicit control on how the instance should be duplicated (limiting fields or related objects) copied and unique field detection.

PyPI Python Django Downloads Dependencies
PyPI version PyPI - Python Version PyPI - Django Version Downloads Updates
Test Vulnerabilities Coverage Code Quality Contributors Code Style
Test Known Vulnerabilities Codacy Badge
codecov
Codacy Badge All Contributors Code style: black

Table of contents

Installation

Run

pip install django-clone

Usage

Inheriting from CloneModel or CloneMixin

Subclassing the CloneModel

from django.db import models
from django.utils.translation import gettext_lazy as _
from model_clone import CloneModel

class TestModel(CloneModel):
    title = models.CharField(max_length=200)
    tags =  models.ManyToManyField('Tags')

    _clone_m2m_fields = ['tags']


class Tags(models.Model):  #  To enable cloning tags directly use `CloneModel` as shown above.
    name = models.CharField(max_length=255)

    def __str__(self):
        return _(self.name)

Using the CloneMixin

from django.db import models
from django.utils.translation import gettext_lazy as _
from model_clone import CloneMixin

class TestModel(CloneMixin, models.Model):
    title = models.CharField(max_length=200)
    tags =  models.ManyToManyField('Tags')

    _clone_m2m_fields = ['tags']


class Tags(models.Model):  #  To enable cloning tags directly use `CloneMixin` as shown above.
    name = models.CharField(max_length=255)

    def __str__(self):
        return _(self.name)

Duplicating a model instance

In [1]: test_obj = TestModel.objects.create(title='New')

In [2]: test_obj.pk
Out[2]: 1

In [3]: test_obj.title
Out[3]: 'New'

In [4]: test_obj.tags.create(name='men')

In [4]: test_obj.tags.create(name='women')

In [5]: test_obj.tags.all()
Out[5]: <QuerySet [<Tag: men>, <Tag: women>]>

In [6]: test_obj_clone = test_obj.make_clone()

In [7]: test_obj_clone.pk
Out[7]: 2

In [8]: test_obj_clone.title
Out[8]: 'New copy 1'

In [9]: test_obj_clone.tags.all()
Out[9]: <QuerySet [<Tag: men>, <Tag: women>]>

Bulk cloning a model

In [1]: test_obj = TestModel.objects.create(title='New')

In [2]: test_obj.pk
Out[2]: 1

In [3]: test_obj.title
Out[3]: 'New'

In [4]: test_obj.tags.create(name='men')

In [4]: test_obj.tags.create(name='women')

In [5]: test_obj.tags.all()
Out[5]: <QuerySet [<Tag: men>, <Tag: women>]>

In [6]: test_obj_clones = test_obj.bulk_clone(1000)

In [7]: len(test_obj_clones)
Out[7]: 1000

In [8]: test_obj_clone = test_obj_clones[0]

In [9]: test_obj_clone.pk
Out[9]: 2

In [10]: test_obj_clone.title
Out[10]: 'New copy 1'

In [11]: test_obj_clone.tags.all()
Out[11]: <QuerySet [<Tag: men>, <Tag: women>]>

CloneMixin attributes

Explicit

Field Names Description
_clone_fields Restrict the list of fields to copy from the instance (By default: Copies all fields excluding auto-created/non editable model fields)
_clone_m2m_fields Restricted Many to many fields (i.e Test.tags)
_clone_m2o_or_o2m_fields Restricted Many to One/One to Many fields
_clone_o2o_fields Restricted One to One fields

Implicit

Field Names (include all except these fields.) Description
_clone_excluded_fields Excluded model fields.
_clone_excluded_m2m_fields Excluded many to many fields.
_clone_excluded_m2o_or_o2m_fields Excluded Many to One/One to Many fields.
_clone_excluded_o2o_fields Excluded one to one fields.

NOTE: :warning:

  • Ensure to either set _clone_excluded_* or _clone_*. Using both would raise errors.

Creating clones without subclassing CloneMixin.

In [1]: from model_clone.utils import create_copy_of_instance

In [2]: test_obj = TestModel.objects.create(title='New')

In [3]: test_obj.pk
Out[3]: 1

In [4]: test_obj.title
Out[4]: 'New'

In [5]: test_obj.tags.create(name='men')

In [6]: test_obj.tags.create(name='women')

In [7]: test_obj.tags.all()
Out[7]: <QuerySet [<Tag: men>, <Tag: women>]>

In [8]: test_obj_clone = create_copy_of_instance(test_obj, attrs={'title': 'Updated title'})

In [9]: test_obj_clone.pk
Out[9]: 2

In [10]: test_obj_clone.title
Out[10]: 'Updated title'

In [11]: test_obj_clone.tags.all()
Out[11]: <QuerySet []>

NOTE: :warning:

  • This method won't copy over related objects like Many to Many/One to Many relationships.
  • Ensure that required fields skipped from being cloned are passed in using the attrs dictionary.

Django Admin

Duplicating Models from the Django Admin view.

Change

from django.contrib import admin
from django.contrib.admin import ModelAdmin

@admin.register(TestModel)
class TestModelAdmin(ModelAdmin):
    pass

to

from model_clone import CloneModelAdmin

@admin.register(TestModel)
class TestModelAdmin(CloneModelAdmin):
    pass
List View

Screenshot

Change View

Screenshot

CloneModelAdmin class attributes

from model_clone import CloneModelAdmin

@admin.register(TestModel)
class TestModelAdmin(CloneModelAdmin):
    # Enables/Disables the Duplicate action in the List view (Defaults to True)
    include_duplicate_action = True
    # Enables/Disables the Duplicate action in the Change view (Defaults to True)
    include_duplicate_object_link = True

NOTE: :warning:

  • Ensure that model_clone is placed before django.contrib.admin
INSTALLED_APPS = [
    'model_clone',
    'django.contrib.admin',
    '...',
]

Found a Bug?

To file a bug or submit a patch, please head over to django-clone on github.

Contributors ✨

Thanks goes to these wonderful people:


Gerben Neven

🐛 ⚠️ 💻

Sebastian Kapunkt

💻 🐛 ⚠️

Andrés Portillo

🐛

WhiteSource Renovate

🚧

Yuekui

💻 🐛 ⚠️

This project follows the all-contributors specification. Contributions of any kind welcome!

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-clone-2.4.0.tar.gz (25.0 kB view details)

Uploaded Source

Built Distribution

django_clone-2.4.0-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

Details for the file django-clone-2.4.0.tar.gz.

File metadata

  • Download URL: django-clone-2.4.0.tar.gz
  • Upload date:
  • Size: 25.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.7.3

File hashes

Hashes for django-clone-2.4.0.tar.gz
Algorithm Hash digest
SHA256 b271c0b9178ffa05fda2067144bd1bf30cae86d3caf71e158b74b5e33fc20f72
MD5 2023647973cd88655a6446e885cb38a8
BLAKE2b-256 c1204a546fb1c5206c9886da2ef8c772f634582d8b1cc6e79164f2944fc17d0e

See more details on using hashes here.

File details

Details for the file django_clone-2.4.0-py3-none-any.whl.

File metadata

  • Download URL: django_clone-2.4.0-py3-none-any.whl
  • Upload date:
  • Size: 19.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.7.3

File hashes

Hashes for django_clone-2.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1a208224d455de99497f6da1a697de68766a6dadf6b845ba268f5c00abf4a42b
MD5 e73e35dcabe1f7006478d5c4431b5824
BLAKE2b-256 dac6462853496a0f7e6cb8de722d1d539672e7cf2c5043121e82eb3ccd862089

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page