%global _empty_manifest_terminate_build 0 Name: python-django-clone Version: 5.3.1 Release: 1 Summary: Create a clone of a django model instance. License: MIT/Apache-2.0 URL: https://github.com/tj-django/django-clone.git Source0: https://mirrors.nju.edu.cn/pypi/web/packages/c4/f0/d5e399c401dfaf7a46451132ed393892929a884909859ae5bdb68620c873/django-clone-5.3.1.tar.gz BuildArch: noarch Requires: python3-django Requires: python3-conditional Requires: python3-six Requires: python3-bump2version Requires: python3-readme-renderer[md] Requires: python3-git-changelog Requires: python3-pip-tools Requires: python3-check-manifest Requires: python3-django Requires: python3-conditional Requires: python3-six Requires: python3-tox Requires: python3-tox-gh-actions Requires: python3-pluggy Requires: python3-mock Requires: python3-unittest-xml-reporting Requires: python3-codacy-coverage Requires: python3-django-migration-fixer Requires: python3-bump2version Requires: python3-readme-renderer[md] Requires: python3-git-changelog Requires: python3-tox Requires: python3-tox-gh-actions Requires: python3-pluggy Requires: python3-mock Requires: python3-unittest-xml-reporting Requires: python3-codacy-coverage Requires: python3-django-migration-fixer %description

4FC889E9-FF59-4E44-9EB6-2AF7DC034C74

| Python | Django | Downloads | Code Style | |:---------:|:-------:|:-----------:|:--------------:| | [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/django_clone.svg)](https://pypi.org/project/django-clone) | [![PyPI - Django Version](https://img.shields.io/pypi/djversions/django_clone.svg)](https://docs.djangoproject.com/en/3.2/releases/) | [![Downloads](https://pepy.tech/badge/django-clone)](https://pepy.tech/project/django-clone) | [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | | PyPI | Test | Vulnerabilities | Coverage | Code Quality | Pre-Commit | |:---------------:|:----:|:---------------:|:--------:|:-------------:|:-------------:| | [![PyPI version](https://badge.fury.io/py/django-clone.svg)](https://badge.fury.io/py/django-clone) | [![Test](https://github.com/tj-django/django-clone/workflows/Test/badge.svg)](https://github.com/tj-django/django-clone/actions?query=workflow%3ATest) | [![Known Vulnerabilities](https://snyk.io/test/github/tj-django/django-clone/badge.svg?targetFile=requirements.txt)](https://snyk.io/test/github/tj-django/django-clone?targetFile=requirements.txt) | [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/b33dd02dbb034d7fa9886a99f5383ea6)](https://www.codacy.com/gh/tj-django/django-clone?utm_source=github.com\&utm_medium=referral\&utm_content=tj-django/django-clone\&utm_campaign=Badge_Coverage)
[![codecov](https://codecov.io/gh/tj-django/django-clone/branch/main/graph/badge.svg?token=2NE21Oe50Q)](https://codecov.io/gh/tj-django/django-clone)| [![Codacy Badge](https://app.codacy.com/project/badge/Grade/b33dd02dbb034d7fa9886a99f5383ea6)](https://www.codacy.com/gh/tj-django/django-clone?utm_source=github.com\&utm_medium=referral\&utm_content=tj-django/django-clone\&utm_campaign=Badge_Grade) | [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/tj-django/django-clone/main.svg)](https://results.pre-commit.ci/latest/github/tj-django/django-clone/main) | ## 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](#installation) * [Usage](#usage) * [Subclassing the `CloneModel`](#subclassing-the-clonemodel) * [Using the `CloneMixin`](#using-the-clonemixin) * [Duplicating a model instance](#duplicating-a-model-instance) * [Bulk cloning a model](#bulk-cloning-a-model) * [Creating clones without subclassing `CloneMixin`.](#creating-clones-without-subclassing-clonemixin) * [CloneMixin attributes](#clonemixin-attributes) * [Explicit (include only these fields)](#explicit-include-only-these-fields) * [Implicit (include all except these fields)](#implicit-include-all-except-these-fields) * [Django Admin](#django-admin) * [Duplicating Models from the Django Admin view.](#duplicating-models-from-the-django-admin-view) * [List View](#list-view) * [Change View](#change-view) * [CloneModelAdmin class attributes](#clonemodeladmin-class-attributes) * [Advanced Usage](#advanced-usage) * [Signals](#signals) * [pre\_clone\_save, post\_clone\_save](#pre_clone_save-post_clone_save) * [Clone Many to Many fields](#clone-many-to-many-fields) * [Using the `CloneModel`](#using-the-clonemodel) * [Using the `CloneMixin`](#using-the-clonemixin-1) * [Multi database support](#multi-database-support) * [Compatibility](#compatibility) * [Running locally](#running-locally) * [Found a Bug?](#found-a-bug) * [Contributors ✨](#contributors-) ## Installation ![](https://user-images.githubusercontent.com/17484350/221386740-aa66df70-eed0-40ed-9c5f-1d3b6c9045c2.png) ## Usage ### Subclassing the `CloneModel` ![](https://user-images.githubusercontent.com/17484350/221387430-efd5508a-2597-4320-9750-5a4c56833edb.png) ### Using the `CloneMixin` ![](https://user-images.githubusercontent.com/17484350/221387397-6ad5475b-6887-4a5f-b6d3-42784f9dfa7c.png) ### Duplicating a model instance ![](https://user-images.githubusercontent.com/17484350/221386600-731a6f45-1704-4834-bcbe-0f57d912faf7.png) ### Bulk cloning a model ![](https://user-images.githubusercontent.com/17484350/221386555-13978280-35a1-4941-8186-a1c6723a0346.png) ### 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. ![](https://user-images.githubusercontent.com/17484350/221385171-add1a0c3-21fc-4c48-bfe9-4f2014ffe035.png) ### CloneMixin attributes | Attribute | Description | |:------------------------------:|:------------:| | `DUPLICATE_SUFFIX` | Suffix to append to duplicates
(NOTE: This requires `USE_DUPLICATE_SUFFIX_FOR_NON_UNIQUE_FIELDS`
to be enabled and supports string fields). | `USE_DUPLICATE_SUFFIX_FOR_NON_UNIQUE_FIELDS` | Enable appending the `DUPLICATE_SUFFIX` to new cloned instances. | `UNIQUE_DUPLICATE_SUFFIX` | Suffix to append to unique fields | `USE_UNIQUE_DUPLICATE_SUFFIX` | Enable appending the `UNIQUE_DUPLICATE_SUFFIX` to new cloned instances. | `MAX_UNIQUE_DUPLICATE_QUERY_ATTEMPTS` | The max query attempt while generating unique values for a case of unique conflicts. | #### Explicit (include only these fields) | Attribute | 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 | | `_clone_linked_m2m_fields` | Restricted Many to Many fields that should be linked to the new instance | #### Implicit (include all except these fields) | Attribute | 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. ### Django Admin #### Duplicating Models from the Django Admin view. ![](https://user-images.githubusercontent.com/17484350/221386874-047989a4-ae4d-4d82-9ef6-2b303001a4c2.png) ##### List View ![Screenshot](Duplicate-action.png) ##### Change View ![Screenshot](Duplicate-button.png) #### CloneModelAdmin class attributes ![](https://user-images.githubusercontent.com/17484350/221387085-e0ca31ee-8c4c-40d9-9ce6-44ff5e6814ff.png) > **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 ![](https://user-images.githubusercontent.com/17484350/221387120-b5219cdb-9f74-4751-b593-2c68db9fd0e0.png) ### Clone Many to Many fields #### Using the `CloneModel` ![](https://user-images.githubusercontent.com/17484350/221387226-572cedbe-e30e-456d-af75-bcd25edec754.png) #### Using the `CloneMixin` ![carbon (37)](https://user-images.githubusercontent.com/17484350/221387393-196bcb4b-e136-4d5b-89cd-0fb28d8e6e6e.png) ![](https://user-images.githubusercontent.com/17484350/221387265-ccf05239-ec0c-47ec-b0ed-6c2e01428aee.png) ### Multi database support ![](https://user-images.githubusercontent.com/17484350/221385217-3a123080-b247-4ef0-b876-e75db1518c92.png) ## Compatibility | Python | Supported version | |--------------|--------------------| | Python2.x | `<=2.5.3` | | Python3.5 | `<=2.9.6` | | Python3.6+ | All versions | | Django | Supported version | |--------------|---------------------| | 1.11 | `<=2.7.2` | | 2.x | All versions | | 3.x | All 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](https://github.com/tj-django/django-clone/issues). If you feel generous and want to show some extra appreciation: Support me with a :star: [![Buy me a coffee][buymeacoffee-shield]][buymeacoffee] [buymeacoffee]: https://www.buymeacoffee.com/jackton1 [buymeacoffee-shield]: https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png ## Contributors ✨ Thanks goes to these wonderful people:
Gerben Neven
Gerben Neven

πŸ› ⚠️ πŸ’»
Sebastian Kapunkt
Sebastian Kapunkt

πŸ’» πŸ› ⚠️
AndrΓ©s Portillo
AndrΓ©s Portillo

πŸ›
WhiteSource Renovate
WhiteSource Renovate

🚧
Yuekui
Yuekui

πŸ’» πŸ› ⚠️ πŸ“– 🚧
Take Weiland
Take Weiland

⚠️ πŸ› πŸ’»
Patrick
Patrick

πŸ› πŸ’»
Amiel Kollek
Amiel Kollek

πŸ’» πŸ› ⚠️
Eric Theise
Eric Theise

πŸ“–
Daniel Schaffer
Daniel Schaffer

πŸ’» ⚠️
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! %package -n python3-django-clone Summary: Create a clone of a django model instance. Provides: python-django-clone BuildRequires: python3-devel BuildRequires: python3-setuptools BuildRequires: python3-pip %description -n python3-django-clone

4FC889E9-FF59-4E44-9EB6-2AF7DC034C74

| Python | Django | Downloads | Code Style | |:---------:|:-------:|:-----------:|:--------------:| | [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/django_clone.svg)](https://pypi.org/project/django-clone) | [![PyPI - Django Version](https://img.shields.io/pypi/djversions/django_clone.svg)](https://docs.djangoproject.com/en/3.2/releases/) | [![Downloads](https://pepy.tech/badge/django-clone)](https://pepy.tech/project/django-clone) | [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | | PyPI | Test | Vulnerabilities | Coverage | Code Quality | Pre-Commit | |:---------------:|:----:|:---------------:|:--------:|:-------------:|:-------------:| | [![PyPI version](https://badge.fury.io/py/django-clone.svg)](https://badge.fury.io/py/django-clone) | [![Test](https://github.com/tj-django/django-clone/workflows/Test/badge.svg)](https://github.com/tj-django/django-clone/actions?query=workflow%3ATest) | [![Known Vulnerabilities](https://snyk.io/test/github/tj-django/django-clone/badge.svg?targetFile=requirements.txt)](https://snyk.io/test/github/tj-django/django-clone?targetFile=requirements.txt) | [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/b33dd02dbb034d7fa9886a99f5383ea6)](https://www.codacy.com/gh/tj-django/django-clone?utm_source=github.com\&utm_medium=referral\&utm_content=tj-django/django-clone\&utm_campaign=Badge_Coverage)
[![codecov](https://codecov.io/gh/tj-django/django-clone/branch/main/graph/badge.svg?token=2NE21Oe50Q)](https://codecov.io/gh/tj-django/django-clone)| [![Codacy Badge](https://app.codacy.com/project/badge/Grade/b33dd02dbb034d7fa9886a99f5383ea6)](https://www.codacy.com/gh/tj-django/django-clone?utm_source=github.com\&utm_medium=referral\&utm_content=tj-django/django-clone\&utm_campaign=Badge_Grade) | [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/tj-django/django-clone/main.svg)](https://results.pre-commit.ci/latest/github/tj-django/django-clone/main) | ## 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](#installation) * [Usage](#usage) * [Subclassing the `CloneModel`](#subclassing-the-clonemodel) * [Using the `CloneMixin`](#using-the-clonemixin) * [Duplicating a model instance](#duplicating-a-model-instance) * [Bulk cloning a model](#bulk-cloning-a-model) * [Creating clones without subclassing `CloneMixin`.](#creating-clones-without-subclassing-clonemixin) * [CloneMixin attributes](#clonemixin-attributes) * [Explicit (include only these fields)](#explicit-include-only-these-fields) * [Implicit (include all except these fields)](#implicit-include-all-except-these-fields) * [Django Admin](#django-admin) * [Duplicating Models from the Django Admin view.](#duplicating-models-from-the-django-admin-view) * [List View](#list-view) * [Change View](#change-view) * [CloneModelAdmin class attributes](#clonemodeladmin-class-attributes) * [Advanced Usage](#advanced-usage) * [Signals](#signals) * [pre\_clone\_save, post\_clone\_save](#pre_clone_save-post_clone_save) * [Clone Many to Many fields](#clone-many-to-many-fields) * [Using the `CloneModel`](#using-the-clonemodel) * [Using the `CloneMixin`](#using-the-clonemixin-1) * [Multi database support](#multi-database-support) * [Compatibility](#compatibility) * [Running locally](#running-locally) * [Found a Bug?](#found-a-bug) * [Contributors ✨](#contributors-) ## Installation ![](https://user-images.githubusercontent.com/17484350/221386740-aa66df70-eed0-40ed-9c5f-1d3b6c9045c2.png) ## Usage ### Subclassing the `CloneModel` ![](https://user-images.githubusercontent.com/17484350/221387430-efd5508a-2597-4320-9750-5a4c56833edb.png) ### Using the `CloneMixin` ![](https://user-images.githubusercontent.com/17484350/221387397-6ad5475b-6887-4a5f-b6d3-42784f9dfa7c.png) ### Duplicating a model instance ![](https://user-images.githubusercontent.com/17484350/221386600-731a6f45-1704-4834-bcbe-0f57d912faf7.png) ### Bulk cloning a model ![](https://user-images.githubusercontent.com/17484350/221386555-13978280-35a1-4941-8186-a1c6723a0346.png) ### 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. ![](https://user-images.githubusercontent.com/17484350/221385171-add1a0c3-21fc-4c48-bfe9-4f2014ffe035.png) ### CloneMixin attributes | Attribute | Description | |:------------------------------:|:------------:| | `DUPLICATE_SUFFIX` | Suffix to append to duplicates
(NOTE: This requires `USE_DUPLICATE_SUFFIX_FOR_NON_UNIQUE_FIELDS`
to be enabled and supports string fields). | `USE_DUPLICATE_SUFFIX_FOR_NON_UNIQUE_FIELDS` | Enable appending the `DUPLICATE_SUFFIX` to new cloned instances. | `UNIQUE_DUPLICATE_SUFFIX` | Suffix to append to unique fields | `USE_UNIQUE_DUPLICATE_SUFFIX` | Enable appending the `UNIQUE_DUPLICATE_SUFFIX` to new cloned instances. | `MAX_UNIQUE_DUPLICATE_QUERY_ATTEMPTS` | The max query attempt while generating unique values for a case of unique conflicts. | #### Explicit (include only these fields) | Attribute | 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 | | `_clone_linked_m2m_fields` | Restricted Many to Many fields that should be linked to the new instance | #### Implicit (include all except these fields) | Attribute | 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. ### Django Admin #### Duplicating Models from the Django Admin view. ![](https://user-images.githubusercontent.com/17484350/221386874-047989a4-ae4d-4d82-9ef6-2b303001a4c2.png) ##### List View ![Screenshot](Duplicate-action.png) ##### Change View ![Screenshot](Duplicate-button.png) #### CloneModelAdmin class attributes ![](https://user-images.githubusercontent.com/17484350/221387085-e0ca31ee-8c4c-40d9-9ce6-44ff5e6814ff.png) > **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 ![](https://user-images.githubusercontent.com/17484350/221387120-b5219cdb-9f74-4751-b593-2c68db9fd0e0.png) ### Clone Many to Many fields #### Using the `CloneModel` ![](https://user-images.githubusercontent.com/17484350/221387226-572cedbe-e30e-456d-af75-bcd25edec754.png) #### Using the `CloneMixin` ![carbon (37)](https://user-images.githubusercontent.com/17484350/221387393-196bcb4b-e136-4d5b-89cd-0fb28d8e6e6e.png) ![](https://user-images.githubusercontent.com/17484350/221387265-ccf05239-ec0c-47ec-b0ed-6c2e01428aee.png) ### Multi database support ![](https://user-images.githubusercontent.com/17484350/221385217-3a123080-b247-4ef0-b876-e75db1518c92.png) ## Compatibility | Python | Supported version | |--------------|--------------------| | Python2.x | `<=2.5.3` | | Python3.5 | `<=2.9.6` | | Python3.6+ | All versions | | Django | Supported version | |--------------|---------------------| | 1.11 | `<=2.7.2` | | 2.x | All versions | | 3.x | All 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](https://github.com/tj-django/django-clone/issues). If you feel generous and want to show some extra appreciation: Support me with a :star: [![Buy me a coffee][buymeacoffee-shield]][buymeacoffee] [buymeacoffee]: https://www.buymeacoffee.com/jackton1 [buymeacoffee-shield]: https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png ## Contributors ✨ Thanks goes to these wonderful people:
Gerben Neven
Gerben Neven

πŸ› ⚠️ πŸ’»
Sebastian Kapunkt
Sebastian Kapunkt

πŸ’» πŸ› ⚠️
AndrΓ©s Portillo
AndrΓ©s Portillo

πŸ›
WhiteSource Renovate
WhiteSource Renovate

🚧
Yuekui
Yuekui

πŸ’» πŸ› ⚠️ πŸ“– 🚧
Take Weiland
Take Weiland

⚠️ πŸ› πŸ’»
Patrick
Patrick

πŸ› πŸ’»
Amiel Kollek
Amiel Kollek

πŸ’» πŸ› ⚠️
Eric Theise
Eric Theise

πŸ“–
Daniel Schaffer
Daniel Schaffer

πŸ’» ⚠️
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! %package help Summary: Development documents and examples for django-clone Provides: python3-django-clone-doc %description help

4FC889E9-FF59-4E44-9EB6-2AF7DC034C74

| Python | Django | Downloads | Code Style | |:---------:|:-------:|:-----------:|:--------------:| | [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/django_clone.svg)](https://pypi.org/project/django-clone) | [![PyPI - Django Version](https://img.shields.io/pypi/djversions/django_clone.svg)](https://docs.djangoproject.com/en/3.2/releases/) | [![Downloads](https://pepy.tech/badge/django-clone)](https://pepy.tech/project/django-clone) | [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | | PyPI | Test | Vulnerabilities | Coverage | Code Quality | Pre-Commit | |:---------------:|:----:|:---------------:|:--------:|:-------------:|:-------------:| | [![PyPI version](https://badge.fury.io/py/django-clone.svg)](https://badge.fury.io/py/django-clone) | [![Test](https://github.com/tj-django/django-clone/workflows/Test/badge.svg)](https://github.com/tj-django/django-clone/actions?query=workflow%3ATest) | [![Known Vulnerabilities](https://snyk.io/test/github/tj-django/django-clone/badge.svg?targetFile=requirements.txt)](https://snyk.io/test/github/tj-django/django-clone?targetFile=requirements.txt) | [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/b33dd02dbb034d7fa9886a99f5383ea6)](https://www.codacy.com/gh/tj-django/django-clone?utm_source=github.com\&utm_medium=referral\&utm_content=tj-django/django-clone\&utm_campaign=Badge_Coverage)
[![codecov](https://codecov.io/gh/tj-django/django-clone/branch/main/graph/badge.svg?token=2NE21Oe50Q)](https://codecov.io/gh/tj-django/django-clone)| [![Codacy Badge](https://app.codacy.com/project/badge/Grade/b33dd02dbb034d7fa9886a99f5383ea6)](https://www.codacy.com/gh/tj-django/django-clone?utm_source=github.com\&utm_medium=referral\&utm_content=tj-django/django-clone\&utm_campaign=Badge_Grade) | [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/tj-django/django-clone/main.svg)](https://results.pre-commit.ci/latest/github/tj-django/django-clone/main) | ## 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](#installation) * [Usage](#usage) * [Subclassing the `CloneModel`](#subclassing-the-clonemodel) * [Using the `CloneMixin`](#using-the-clonemixin) * [Duplicating a model instance](#duplicating-a-model-instance) * [Bulk cloning a model](#bulk-cloning-a-model) * [Creating clones without subclassing `CloneMixin`.](#creating-clones-without-subclassing-clonemixin) * [CloneMixin attributes](#clonemixin-attributes) * [Explicit (include only these fields)](#explicit-include-only-these-fields) * [Implicit (include all except these fields)](#implicit-include-all-except-these-fields) * [Django Admin](#django-admin) * [Duplicating Models from the Django Admin view.](#duplicating-models-from-the-django-admin-view) * [List View](#list-view) * [Change View](#change-view) * [CloneModelAdmin class attributes](#clonemodeladmin-class-attributes) * [Advanced Usage](#advanced-usage) * [Signals](#signals) * [pre\_clone\_save, post\_clone\_save](#pre_clone_save-post_clone_save) * [Clone Many to Many fields](#clone-many-to-many-fields) * [Using the `CloneModel`](#using-the-clonemodel) * [Using the `CloneMixin`](#using-the-clonemixin-1) * [Multi database support](#multi-database-support) * [Compatibility](#compatibility) * [Running locally](#running-locally) * [Found a Bug?](#found-a-bug) * [Contributors ✨](#contributors-) ## Installation ![](https://user-images.githubusercontent.com/17484350/221386740-aa66df70-eed0-40ed-9c5f-1d3b6c9045c2.png) ## Usage ### Subclassing the `CloneModel` ![](https://user-images.githubusercontent.com/17484350/221387430-efd5508a-2597-4320-9750-5a4c56833edb.png) ### Using the `CloneMixin` ![](https://user-images.githubusercontent.com/17484350/221387397-6ad5475b-6887-4a5f-b6d3-42784f9dfa7c.png) ### Duplicating a model instance ![](https://user-images.githubusercontent.com/17484350/221386600-731a6f45-1704-4834-bcbe-0f57d912faf7.png) ### Bulk cloning a model ![](https://user-images.githubusercontent.com/17484350/221386555-13978280-35a1-4941-8186-a1c6723a0346.png) ### 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. ![](https://user-images.githubusercontent.com/17484350/221385171-add1a0c3-21fc-4c48-bfe9-4f2014ffe035.png) ### CloneMixin attributes | Attribute | Description | |:------------------------------:|:------------:| | `DUPLICATE_SUFFIX` | Suffix to append to duplicates
(NOTE: This requires `USE_DUPLICATE_SUFFIX_FOR_NON_UNIQUE_FIELDS`
to be enabled and supports string fields). | `USE_DUPLICATE_SUFFIX_FOR_NON_UNIQUE_FIELDS` | Enable appending the `DUPLICATE_SUFFIX` to new cloned instances. | `UNIQUE_DUPLICATE_SUFFIX` | Suffix to append to unique fields | `USE_UNIQUE_DUPLICATE_SUFFIX` | Enable appending the `UNIQUE_DUPLICATE_SUFFIX` to new cloned instances. | `MAX_UNIQUE_DUPLICATE_QUERY_ATTEMPTS` | The max query attempt while generating unique values for a case of unique conflicts. | #### Explicit (include only these fields) | Attribute | 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 | | `_clone_linked_m2m_fields` | Restricted Many to Many fields that should be linked to the new instance | #### Implicit (include all except these fields) | Attribute | 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. ### Django Admin #### Duplicating Models from the Django Admin view. ![](https://user-images.githubusercontent.com/17484350/221386874-047989a4-ae4d-4d82-9ef6-2b303001a4c2.png) ##### List View ![Screenshot](Duplicate-action.png) ##### Change View ![Screenshot](Duplicate-button.png) #### CloneModelAdmin class attributes ![](https://user-images.githubusercontent.com/17484350/221387085-e0ca31ee-8c4c-40d9-9ce6-44ff5e6814ff.png) > **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 ![](https://user-images.githubusercontent.com/17484350/221387120-b5219cdb-9f74-4751-b593-2c68db9fd0e0.png) ### Clone Many to Many fields #### Using the `CloneModel` ![](https://user-images.githubusercontent.com/17484350/221387226-572cedbe-e30e-456d-af75-bcd25edec754.png) #### Using the `CloneMixin` ![carbon (37)](https://user-images.githubusercontent.com/17484350/221387393-196bcb4b-e136-4d5b-89cd-0fb28d8e6e6e.png) ![](https://user-images.githubusercontent.com/17484350/221387265-ccf05239-ec0c-47ec-b0ed-6c2e01428aee.png) ### Multi database support ![](https://user-images.githubusercontent.com/17484350/221385217-3a123080-b247-4ef0-b876-e75db1518c92.png) ## Compatibility | Python | Supported version | |--------------|--------------------| | Python2.x | `<=2.5.3` | | Python3.5 | `<=2.9.6` | | Python3.6+ | All versions | | Django | Supported version | |--------------|---------------------| | 1.11 | `<=2.7.2` | | 2.x | All versions | | 3.x | All 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](https://github.com/tj-django/django-clone/issues). If you feel generous and want to show some extra appreciation: Support me with a :star: [![Buy me a coffee][buymeacoffee-shield]][buymeacoffee] [buymeacoffee]: https://www.buymeacoffee.com/jackton1 [buymeacoffee-shield]: https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png ## Contributors ✨ Thanks goes to these wonderful people:
Gerben Neven
Gerben Neven

πŸ› ⚠️ πŸ’»
Sebastian Kapunkt
Sebastian Kapunkt

πŸ’» πŸ› ⚠️
AndrΓ©s Portillo
AndrΓ©s Portillo

πŸ›
WhiteSource Renovate
WhiteSource Renovate

🚧
Yuekui
Yuekui

πŸ’» πŸ› ⚠️ πŸ“– 🚧
Take Weiland
Take Weiland

⚠️ πŸ› πŸ’»
Patrick
Patrick

πŸ› πŸ’»
Amiel Kollek
Amiel Kollek

πŸ’» πŸ› ⚠️
Eric Theise
Eric Theise

πŸ“–
Daniel Schaffer
Daniel Schaffer

πŸ’» ⚠️
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! %prep %autosetup -n django-clone-5.3.1 %build %py3_build %install %py3_install install -d -m755 %{buildroot}/%{_pkgdocdir} if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi pushd %{buildroot} if [ -d usr/lib ]; then find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst fi if [ -d usr/lib64 ]; then find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst fi if [ -d usr/bin ]; then find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst fi if [ -d usr/sbin ]; then find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst fi touch doclist.lst if [ -d usr/share/man ]; then find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst fi popd mv %{buildroot}/filelist.lst . mv %{buildroot}/doclist.lst . %files -n python3-django-clone -f filelist.lst %dir %{python3_sitelib}/* %files help -f doclist.lst %{_docdir}/* %changelog * Tue Apr 25 2023 Python_Bot - 5.3.1-1 - Package Spec generated