GitPedia

Django clone

Controlled Django model instance replication.

From tj-django·Updated June 18, 2026·View on GitHub·

Create copies of a model instance with explicit control on how the instance should be duplicated (limiting fields or related objects copied) with unique field detection. The project is written primarily in Python, distributed under the MIT License license, first published in 2019. Key topics include: bulk-cloning, clone, clonemixin-attributes, cloning, datamodels.

Latest release: v5.5.0
June 10, 2025View Changelog →
<p align="center"> <img width="466" alt="4FC889E9-FF59-4E44-9EB6-2AF7DC034C74" src="https://user-images.githubusercontent.com/17484350/215616634-17439a58-7bd8-4e9c-989f-e6bef7c73e48.png"> </p>
PythonDjangoDownloadsCode Style
PyPI - Python VersionPyPI - Django VersionDownloadsCode style: black
PyPITestVulnerabilitiesCoverageCode QualityPre-Commit
PyPI versionTestKnown VulnerabilitiesCodacy Badge <br/> codecovCodacy Badgepre-commit.ci status

django-clone

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

This solves the problem introduced by using instance.pk = None and instance.save() which results in copying more object state than required.

Features

  • 100% test coverage.
  • More control over how a model instance should be duplicated
  • Multi Database support i.e Create duplicates on one or more databases.
  • Restrict fields used for creating a duplicate instance.
  • Detects unique fields and naively adds a suffix copy {count} to each duplicate instance (for supported fields only).
  • Optionally differentiate between a duplicate instance and the original by appending a copy suffix to non unique fields (for supported fields only).

Table of Contents

Installation

pip

bash
pip install django-clone

poetry

bash
poetry add django-clone

Usage

Subclassing the CloneModel

Using the CloneMixin

Using the CloneModel

Duplicating a model instance

Bulk cloning a model

Creating clones without subclassing CloneMixin.

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 kwargs.

CloneMixin attributes

AttributeDescription
DUPLICATE_SUFFIXSuffix to append to duplicates <br> (NOTE: This requires USE_DUPLICATE_SUFFIX_FOR_NON_UNIQUE_FIELDS <br> to be enabled and supports string fields).
USE_DUPLICATE_SUFFIX_FOR_NON_UNIQUE_FIELDSEnable appending the DUPLICATE_SUFFIX to new cloned instances.
UNIQUE_DUPLICATE_SUFFIXSuffix to append to unique fields
USE_UNIQUE_DUPLICATE_SUFFIXEnable appending the UNIQUE_DUPLICATE_SUFFIX to new cloned instances.
MAX_UNIQUE_DUPLICATE_QUERY_ATTEMPTSThe max query attempt while generating unique values for a case of unique conflicts.

Explicit (include only these fields)

AttributeDescription
_clone_fieldsRestrict the list of fields to copy from the instance (By default: Copies all fields excluding auto-created/non editable model fields)
_clone_m2m_fieldsRestricted Many to many fields (i.e Test.tags)
_clone_m2o_or_o2m_fieldsRestricted Many to One/One to Many fields
_clone_o2o_fieldsRestricted One to One fields
_clone_linked_m2m_fieldsRestricted Many to Many fields that should be linked to the new instance

Implicit (include all except these fields)

AttributeDescription
_clone_excluded_fieldsExcluded model fields.
_clone_excluded_m2m_fieldsExcluded many to many fields.
_clone_excluded_m2o_or_o2m_fieldsExcluded Many to One/One to Many fields.
_clone_excluded_o2o_fieldsExcluded one to one fields.

NOTE: :warning:

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

Django Admin

Duplicating Models from the Django Admin view.

List View

Screenshot

Change View

Screenshot

CloneModelAdmin class attributes

NOTE: :warning:

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

Advanced Usage

Signals

pre_clone_save, post_clone_save

Multi-database support

Compatibility

PythonSupported version
Python2.x<=2.5.3
Python3.5<=2.9.6
Python3.6+<=5.3.3
Python3.7+All versions
DjangoSupported version
1.11<=2.7.2
2.xAll versions
3.xAll versions
4.xAll versions

Running locally

shell
$ git clone git@github.com:tj-django/django-clone.git $ make default-user $ make run

Spins up a django server running the demo app.

Visit http://127.0.0.1:8000

Found a Bug?

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

If you feel generous and want to show some extra appreciation:

Support me with a :star:

Buy me a coffee

Contributors ✨

Thanks goes to these wonderful people:

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> <!-- prettier-ignore-start --> <!-- markdownlint-disable --> <table> <tbody> <tr> <td align="center" valign="top" width="14.28%"><a href="http://gerritneven.nl"><img src="https://avatars1.githubusercontent.com/u/2500973?v=4?s=100" width="100px;" alt="Gerben Neven"/><br /><sub><b>Gerben Neven</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/issues?q=author%3Agerbyzation" title="Bug reports">🐛</a> <a href="https://github.com/tj-django/django-clone/commits?author=gerbyzation" title="Tests">⚠️</a> <a href="https://github.com/tj-django/django-clone/commits?author=gerbyzation" title="Code">💻</a></td> <td align="center" valign="top" width="14.28%"><a href="http://sebastian-kindt.com"><img src="https://avatars1.githubusercontent.com/u/2536081?v=4?s=100" width="100px;" alt="Sebastian Kapunkt"/><br /><sub><b>Sebastian Kapunkt</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/commits?author=SebastianKapunkt" title="Code">💻</a> <a href="https://github.com/tj-django/django-clone/issues?q=author%3ASebastianKapunkt" title="Bug reports">🐛</a> <a href="https://github.com/tj-django/django-clone/commits?author=SebastianKapunkt" title="Tests">⚠️</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/andresp99999"><img src="https://avatars0.githubusercontent.com/u/1036725?v=4?s=100" width="100px;" alt="Andrés Portillo"/><br /><sub><b>Andrés Portillo</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/issues?q=author%3Aandresp99999" title="Bug reports">🐛</a></td> <td align="center" valign="top" width="14.28%"><a href="https://renovate.whitesourcesoftware.com"><img src="https://avatars0.githubusercontent.com/u/25180681?v=4?s=100" width="100px;" alt="WhiteSource Renovate"/><br /><sub><b>WhiteSource Renovate</b></sub></a><br /><a href="#maintenance-renovate-bot" title="Maintenance">🚧</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/yuekui"><img src="https://avatars2.githubusercontent.com/u/2561450?v=4?s=100" width="100px;" alt="Yuekui"/><br /><sub><b>Yuekui</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/commits?author=yuekui" title="Code">💻</a> <a href="https://github.com/tj-django/django-clone/issues?q=author%3Ayuekui" title="Bug reports">🐛</a> <a href="https://github.com/tj-django/django-clone/commits?author=yuekui" title="Tests">⚠️</a> <a href="https://github.com/tj-django/django-clone/commits?author=yuekui" title="Documentation">📖</a> <a href="#maintenance-yuekui" title="Maintenance">🚧</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/diesieben07"><img src="https://avatars.githubusercontent.com/u/1915984?v=4?s=100" width="100px;" alt="Take Weiland"/><br /><sub><b>Take Weiland</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/commits?author=diesieben07" title="Tests">⚠️</a> <a href="https://github.com/tj-django/django-clone/issues?q=author%3Adiesieben07" title="Bug reports">🐛</a> <a href="https://github.com/tj-django/django-clone/commits?author=diesieben07" title="Code">💻</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/ptrck"><img src="https://avatars.githubusercontent.com/u/1259703?v=4?s=100" width="100px;" alt="Patrick"/><br /><sub><b>Patrick</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/issues?q=author%3Aptrck" title="Bug reports">🐛</a> <a href="https://github.com/tj-django/django-clone/commits?author=ptrck" title="Code">💻</a></td> </tr> <tr> <td align="center" valign="top" width="14.28%"><a href="https://github.com/Akollek"><img src="https://avatars.githubusercontent.com/u/5873158?v=4?s=100" width="100px;" alt="Amiel Kollek"/><br /><sub><b>Amiel Kollek</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/commits?author=Akollek" title="Code">💻</a> <a href="https://github.com/tj-django/django-clone/issues?q=author%3AAkollek" title="Bug reports">🐛</a> <a href="https://github.com/tj-django/django-clone/commits?author=Akollek" title="Tests">⚠️</a></td> <td align="center" valign="top" width="14.28%"><a href="https://erictheise.com/"><img src="https://avatars.githubusercontent.com/u/317680?v=4?s=100" width="100px;" alt="Eric Theise"/><br /><sub><b>Eric Theise</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/commits?author=erictheise" title="Documentation">📖</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/DanielSchaffer"><img src="https://avatars.githubusercontent.com/u/334487?v=4?s=100" width="100px;" alt="Daniel Schaffer"/><br /><sub><b>Daniel Schaffer</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/commits?author=DanielSchaffer" title="Code">💻</a> <a href="https://github.com/tj-django/django-clone/commits?author=DanielSchaffer" title="Tests">⚠️</a></td> <td align="center" valign="top" width="14.28%"><a href="http://damianb.dev"><img src="https://avatars.githubusercontent.com/u/4206989?v=4?s=100" width="100px;" alt="Damian Barabonkov"/><br /><sub><b>Damian Barabonkov</b></sub></a><br /><a href="https://github.com/tj-django/django-clone/commits?author=DamianB-BitFlipper" title="Code">💻</a> <a href="https://github.com/tj-django/django-clone/commits?author=DamianB-BitFlipper" title="Tests">⚠️</a></td> </tr> </tbody> </table> <!-- markdownlint-restore --> <!-- prettier-ignore-end --> <!-- ALL-CONTRIBUTORS-LIST:END -->

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

Contributors

Showing top 12 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from tj-django/django-clone via the GitHub API.Last fetched: 6/27/2026