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.

Tags: database, django, models

 

Kommentare

Kommentar von mzwjao (21.02.2010, 21:05)

vzozvmbusfnscxcvvusznbnessnvmc

 

 

Kommentar schreiben