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 |
---|---|---|---|---|
Test | Vulnerabilities | Coverage | Code Quality | Contributors | Code Style |
---|---|---|---|---|---|
|
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. |
:warning: NOTE: 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 []>
:warning: NOTE:
- 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
Change View
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
:warning: NOTE: Ensure that
model_clone
is placed beforedjango.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
Built Distribution
File details
Details for the file django-clone-2.1.1.tar.gz
.
File metadata
- Download URL: django-clone-2.1.1.tar.gz
- Upload date:
- Size: 22.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.7.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | adcb154071c7dc0c8f15989bd190182b7a53fbfc06918df212d6137aa54a1f77 |
|
MD5 | b8f93ac3f2e0fb833a7dddcbd481f41d |
|
BLAKE2b-256 | 7b3ea37fbdb4f575099f61d658485635132195683679a32c633ef083fb6d4823 |
File details
Details for the file django_clone-2.1.1-py3-none-any.whl
.
File metadata
- Download URL: django_clone-2.1.1-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.7.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2caa590cd97f338538a3290c4b198a0dff4ef1aae6aac1ce3ccfba1d8db7dcf2 |
|
MD5 | cb4767f9b323ca3eb1833d997abbbf16 |
|
BLAKE2b-256 | 9d3182d2ba2129759f3ba1e6ced45628b4f02b7def39207c6c8a7ecc528834c0 |