Copy or clone an object instance in Django/Python

10,088

You can duplicate any existing django model instance by clearing its primary key, and then saving it again.

ct = CourseTemplate.objects.all()[0]
print ct.pk
# some original pk

ct.pk = None
ct.save()
print ct.pk
# will be a new auto-incremented 
Share:
10,088
TastyEquation60
Author by

TastyEquation60

Head of Product at divio.com, the company behind Aldryn and backers of django-CMS.

Updated on June 05, 2022

Comments

  • TastyEquation60
    TastyEquation60 almost 2 years

    I've following scenario:

    class CourseTemplate(models.Model):
        title = models.CharField(max_length=70)
        teacher = models.ForeignKey(User)
        description = models.TextField()
    
        max_students = models.IntegerField()
        sessions = models.ManyToManyField(CourseSession) # e.g. Session 1 Introduction, Session 2 Basics, etc.
        rating = models.ManyToManyFields(StudentRating)
        date_added = models.DateTimeField()
    
    class CourseEnrollment(models.Model):
        course = models.OneToOneField(CourseTemplate) # Each enrollment needs a new CourseTemplate Instance, so I can track it
        students = models.ManyToManyField(User)
    
    Class CourseSession(models.Model):
        title = models.CharField(max_length=50)
        date = models.DateTimeField()
        details = models.CharField(max_length=100)
        address = models.TextField()
        #parent_course = models.ForeignKey(CourseTemplate)
    
    class StudentRating(models.Model):
        student = models.ForeignKey(User)
        rating = models.IntegerField()
        #course = models.ForeignKey(CourseTemplate)
    

    Now a teacher (=User) can create a CourseTemplate with all the required details first. After it's saved, he can create a concrete "enrollment" for e.g. this semester with 5 sessions. Maybe he changes after 8 enrollments some details (e.g. CourseTemplate.description or the course now only has 7 sessions instead of 8).

    I'd like to have a 1:1 relationship between each CourseTemplate instance and each CourseEnrollment, so I can see for example: - Teacher X had 2012 three CourseEnrollments, two of them were the same or - which rating has he received for his second course.

    The presented "Template" should always be the "newest", so I'd just need to get the latest instance by CourseTemplate.date_added.

    Does anyone know how I can avoid this problem?

    Thanks a lot!

  • TastyEquation60
    TastyEquation60 over 11 years
    Will the original 'ct' be still available (especially as reference for other CourseEnrollment instances) after clearing the PK?
  • jdi
    jdi over 11 years
    Yep. Doesn't hurt the original. The save method just sees that there is no pk and does an insert. You will need to query down the original ct again though, since this ct will now be the new clone.
  • odedfos
    odedfos about 10 years
    If you already have the source instance and you'd like to avoid the extra db access you could also use: ct2=copy(ct) where copy came from: from copy import copy. Then clear the pk.
  • gonz
    gonz almost 10 years
    In case you are looking for it too: link to the documentation (django 1.6). Watch out for the special case mentioned there about model inheritance.