6

ok i think this is very basic, but since I am new to Django I don't know how to handle this.

I need to copy an instance of a django-model. As explained here, there is a problem with copying ManyToMany relations. But the attachment "django-model-copying.diff" has that function I guess. So I don't know - does my Django already have that function? I don't know how to call it. Help would be appreciated.

7
  • "I need to copy a whole django-model"? Do you mean clone an instance of the model -- i.e., clone a row in a database. This is -- generally -- a terrible idea. Why would you be cloning database rows? The whole point of the relational model of data is to make cloning a row needless. What are you doing? Commented Sep 30, 2010 at 19:46
  • yeah, your right - i need to copy an instance of a model.. I want to copy an instance with all its attributes and relations to other models.. You know, i thought about redundancy and stuff - but for my problem - it's the best way to just copy it. Commented Sep 30, 2010 at 19:57
  • @Peter: "but for my problem - it's the best way to just copy it". Sorry, but it isn't. It can't be. You have "relationships" in the database that make this completely needless. Perhaps you need to fix your data model before you go too far down this road. Commented Sep 30, 2010 at 20:02
  • Thanks for your quick response S.Lott! Ok, i'll try to explain.. So we have 2 models: User and Book. A User has a book called "Titanic" with some content. Now, another user wants a relation to that book too. But, the second user wants exactly the same book, but it should be called "Ship is going under".. I would copy the book, and rename it. - I know, i could also put the content of the book in another model - but my model is a little bit more complex. Not much is copied and im sure i need it this way.. Soo, can you help me use the function i mentiond in the title? thanks in advance Commented Sep 30, 2010 at 20:11
  • that's not an instance copy of a model, it's a new row with different data Commented Sep 30, 2010 at 20:16

4 Answers 4

5

The docs include directions on how to do this - including how to handle many to many relationships.

Sign up to request clarification or add additional context in comments.

Comments

4

You can just do the following:

m = MyModel.objects.get(pk=1)
m.id = None
m.save()

That way new instance will be created with new id of course in case of any unique properties it will trigger errors during validation.

NOTE: As for the function you've mentioned - it is not yet added to the trunk, the status is design decision needed, but if you know what you're doing you can manually apply the diff to your django instance - it's called patching btw. Here are some details about how to do it: http://ariejan.net/2007/07/03/how-to-create-and-apply-a-patch-with-subversion/.

4 Comments

I guess you could add __copy__()/__deepcopy__() functions to your model and then save the m2m values. Or maybe using pickle.. I'll try to solve this one out - quite interesting ;)
Problem is that you have to copy 'through' table also, to point the new model on one end while pointing to the other end of the relation..
As Peter and bx2 already mentionned, this doesn't address the main problem which is m2m relationships.
Also doesn't work with Django 1.2+ - you need to set m.pk = None as well -- and doesn't fix m2m problem.
1

I'll try to answer your actual problem, because what you are asking for in the question is a problem with your proposed solution, which as many have pointed out is not really ideal.

In the comments you mention this:

i'll try to explain.. So we have 2 models: User and Book. A User has a book called "Titanic" with some content. Now, another user wants a relation to that book too. But, the second user wants exactly the same book, but it should be called "Ship is going under".. I would copy the book, and rename it. - I know, i could also put the content of the book in another model - but my model is a little bit more complex.

Looks like you have three things to track:

  1. Users
  2. Their Books
  3. Some custom notes that users have about their "owned" book.

For each Book, store its common information, for example:

class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

    def __unicode__(self):
        return unicode(self.name)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ManyToMany(Author)
    isbn = models.CharField(max_length=13)
    # and so on

    def __unicode__(self):
        return unicode(self.title)

Now, you need to store Book -> User relation, such as one user can have many books, two users may own the same book, with their own meta information attached.

class BookClub(models.Model):
     username = models.ForeignKey(User)
     book = models.ForeignKey(Book)
     comments = models.TextField()

If you structure your models like that, you'll be able to do queries like:

  • "How many books does each member have?"
  • "What is the most popular book?"
  • "What is the least popular book?"
  • "What is the most popular author?"

Comments

0

It's worth noting that as of django 1.8 you may have UUIDFields. If you copy a model instance and then save it the unique constraint will fail on this column, in which case you have to do something like:

import uuid
m = MyModel.objects.get(pk=1)
m.pk = None
m.uuid = uuid.uuid4() //generate new uuid
m.save()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.