I've models for Books
, Chapters
and Pages
. They are all written by a User
:
from django.db import models
class Book(models.Model)
author = models.ForeignKey('auth.User')
class Chapter(models.Model)
author = models.ForeignKey('auth.User')
book = models.ForeignKey(Book)
class Page(models.Model)
author = models.ForeignKey('auth.User')
book = models.ForeignKey(Book)
chapter = models.ForeignKey(Chapter)
What I'd like to do is duplicate an existing Book
and update it's User
to someone else. The wrinkle is I would also like to duplicate all related model instances to the Book
- all it's Chapters
and Pages
as well!
Things get really tricky when look at a Page
- not only will the new Pages
need to have their author
field updated but they will also need to point to the new Chapter
objects!
Does Django support an out of the box way of doing this? What would a generic algorithm for duplicating a model look like?
Cheers,
John
Update:
The classes given above are just an example to illustrate the problem I'm having!
I haven't tried it in django but python's deepcopy might just work for you
EDIT:
You can define custom copy behavior for your models if you implement functions:
If there's just a couple copies in the database you're building, I've found you can just use the back button in the admin interface, change the necessary fields and save the instance again. This has worked for me in cases where, for instance, I need to build a "gimlet" and a "vodka gimlet" cocktail where the only difference is replacing the name and an ingredient. Obviously, this requires a little foresight of the data and isn't as powerful as overriding django's copy/deepcopy - but it may do the trick for some.
Django does have a built-in way to duplicate an object via the admin - as answered here: In the Django admin interface, is there a way to duplicate an item?
I had no luck with any of the answers here with Django 2.1.2, so I created a generic way of performing a deep copy of a database model that is heavily based on the answers posted above.
The key differences from the answers above is that
ForeignKey
no longer has an attribute calledrel
, so it has to be changed tof.remote_field.model
etc.Furthermore, because of the difficulty of knowing the order the database models should be copied in, I created a simple queuing system that pushes the current model to the end of the list if it is unsuccessfully copied. The code is postet below:
I hope it is of any help :)
The duplication error is just a simple exception extension:
Using the CollectedObjects snippet above no longer works but can be done with the following modification:
and
instead of CollectorObjects
I think you'd be happier with a simpler data model, also.
Is it really true that a Page is in some Chapter but a different book?
It seems like your model is too complex.
I think you'd be happier with something simpler. I'm just guessing at this, since I don't your know entire problem.
Each page has distinct authorship. Each chapter, then, has a collection of authors, as does the book. Now you can duplicate Book, Chapter and Pages, assigning the cloned Pages to the new Author.
Indeed, you might want to have a many-to-many relationship between Page and Chapter, allowing you to have multiple copies of just the Page, without cloning book and Chapter.