Model-Instances kopieren
Veröffentlich am 10.03.2009, 23:08
Ich war heute auf der Suche nach einer Möglichkeit, eine komplette Model-Instance inkl. aller Daten (normale Felder, ForeignKeys, Many-to-Many Feldern und Dateien) zu kopieren. Es sollte ein vollständiges Duplikat erzeugt werden.
Da ich nicht fündig geworden bin, möchte ich euch meine Implementierung nicht vorenthalten:
from django.db import models
from django.conf import settings
import os
import shutil
class CloneableModel(models.Model):
def clone(self):
initial = dict([(f.name, getattr(self, f.name))
for f in self._meta.fields if \
not isinstance(f, models.AutoField) \
and not isinstance(f, models.FileField) \
and not f in self._meta.parents.values()])
obj = self.__class__(**initial)
obj.save()
for field in [f.name for f in self._meta.many_to_many]:
oldfield = getattr(self, field)
setattr(obj, field, oldfield.all())
for field in [f.name for f in self._meta.fields if isinstance(f, models.FileField)]:
oldfield = getattr(self, field)
newfield = getattr(obj, field)
if oldfield:
newpath = newfield.field.storage.get_available_name(oldfield.name)
shutil.copy(
oldfield.path,
os.path.join(settings.MEDIA_ROOT, newpath)
)
setattr(obj, field, newpath)
obj.save()
return obj
class Meta:
abstract = True
Dieses Stück Code irgendwo in eurem Projekt abspeichern und die betroffenen Models von dieser Klasse statt von models.Model erben lassen. Dadurch erhalten euere Models eine zusätzliche Methode clone.
Diese Methode kopiert das gesamte Objekt mitsamt m2m Feldern und Dateien. Bei den Dateien ist zu beachten, dass jede Datei auch auf Filesystem Ebene kopiert wird, es wird also keine Referenz auf die Datei des alten Objekts angegeben.
Danke an Michael Elsdoerfer für die Grundidee.
Kommentare
Kommentar von mzwjao (21.02.2010, 21:05)
vzozvmbusfnscxcvvusznbnessnvmc