Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Django / Clone a model instance, exclude fields optionally
from typing import Any, Dict, List, Tuple, Optional
from django.db.models import Model, ManyToManyField
from django.db.models.fields import Field
def clone_model_instance(
instance: Model, exclude: Optional[Tuple[str]] = None, commit=True
) -> Model:
exclude = exclude or ()
concrete_fields: List[Field] = instance.__class__._meta.concrete_fields
many_to_many: List[ManyToManyField] = instance.__class__._meta.many_to_many
# Exclude some fields
fields = filter(
lambda field: field.name not in exclude
and field not in many_to_many
and not field.auto_created
and not field.primary_key,
concrete_fields,
)
# Assign the values and set defaults
values: Dict[str, Any] = {
field.attname: getattr(instance, field.attname, field.get_default()) for field in fields
}
new_obj: Model = instance.__class__(**values)
new_obj.full_clean(exclude=exclude)
if commit:
new_obj.save()
return new_obj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment