Copy Model Object in Django
I ran into a situation where I wanted to created a new database record from an existing record (model object). I figured there should be a fairly simple solution. It turns out there is and I want to thank Seveas on IRC #django for pointing it out for me. This is essentially what I did:
from copy import deepcopy
old_obj = deepcopy(obj)
old_obj.id = None
old_obj.save()
Voila!
Related posts:
- Mobile App on Subdomain with Django I’ve noticed a fairly common pattern arising with mobile and...
- Django & Djson… er, JSON I must admin this is my first attempt at even...
- Django: Filter Model on Date Range I’m sure this is in the documentation *somewhere* but it...
- One Click Django Project Publishing I was reading The Joel Test and I got to...
- Django cron on Webfaction James Bennett addresses one of the most frequently asked questions...
Related posts brought to you by Yet Another Related Posts Plugin.
November 5, 2009
Tags: django Posted in: Programming & Internet




17 Responses
It’s worth noting that this won’t actually copy any related objects at the DB level, so while at the Python level you’ll have different related objects at the DB level teh foreign keys will still point to the same row.
my version:
def copy_db_obj(from_obj,to_obj,flds_excluded=[],include_id=False,auto_save=True):
if not include_id:
flds_excluded += ['id']
flds = []
for f in from_obj._meta.fields:
flds.append(f.attname)
for fld in flds:
if not fld in flds_excluded:
setattr(to_obj, fld, getattr(from_obj, fld))
if auto_save:
to_obj.save()
return to_obj.id
I don’t get the deepcopy().
If all you wanted is a different row in the DB, there shouldn’t be the need to copy at Python level, just set id to None and save – the ORM will issue a INSERT instead of UPDATE.
If you want to copy just create the constructor and then copy the content of old object into new one and then Update it, i m sure that will work
If all you wanted is a different row in the DB, there shouldn’t be the need to copy at Python level, just set id to None and save – the ORM will issue a INSERT instead of UPDATE.
yes Alex is right, on DB level object will not be identified as it can only point to primary key and not to specific id, hence it can be possible on language level.
The most important thing to me is that copying objects should work in a clean way (setting the primary key to None is more or less clean enough, provided that it is documented somewhere and works as expected). Such a possibility is needed sometimes: I have to maintain a large number of objecs which often differ only in one field, so I can simply copy the old one and change the value.
it is really easy if you have maintained your database, so that by just applying LIFO you can search the particular field and copy the object or modify the value wherever you want.
I tend to try and not snoop around in my databases because then things start going wonky.
I wrote a first version of the patch: it implements copy() as method of the Model class defined in base.py. It was tested by a small helper script – I’m not sure, but it probably needs some unittests, too. As this was my first patch submitted to Django, I was not sure how to implement it correctly, so this patch is more of a draft that is free to discussion. If you have any comments on it – just post, I’ll try to improve this patch to bring it into a stage where it is ready for checkin.
Many-to-many fields can only be added and saved after the models they are referring to have been saved (or, at least, have a primary key). That cannot be avoided. So it sounds like you need to write an external copy() function that handles this. Seems like a reasonable thing to do, so feel free to knock up a patch. A method on the Model class wouldn’t be insane.
Better to make a Main class and then create a sub class using constructor, later on you can make new object and add copy old data to new one, this will surely create a copy in main class.
yes this will surely work, creating new class and then creating object will assign the new value to only main class and the copied object will not get mixed with the old ones.
You can define custom copy behavior for your models if you implement functions:
__copy__() and __deepcopy__()
There is no way to have Django return, say, a MyUser object whenever you query for User objects. A queryset for User objects will return those types of objects. The whole point of proxy objects is that code relying on the original User will use those and your own code can use the extensions you included (that no other code is relying on anyway). It is not a way to replace the User (or any other) model everywhere with something of your own creation.
A readable-and-writable, dictionary-like object that represents the current session. This is only available if your Django installation has session support activated. See the session documentation for full details.
ith the exception of CONTENT_LENGTH and CONTENT_TYPE, as given above, any HTTP headers in the request are converted to META keys by converting all characters to uppercase, replacing any hyphens with underscores and adding an HTTP_ prefix to the name. So, for example, a header called X-Bender would be mapped to the META key HTTP_X_BENDER.
Leave a Reply