Instances with deferred fields cannot be used for copying.
As per documentation, it's possible to clone objects by setting pk = None
.
However, if the object to clone comes from a deferred queryset (after calling defer
or only
), trying to save the copy raises some hard to decipher exceptions.
class DeferCloneTest(TestCase):
@classmethod
def setUpTestData(cls):
SimpleItem.objects.create(name="test", value=42)
def _get_item(self):
item = SimpleItem.objects.defer('value').first() # same with `only` instead of `defer`
item.pk = None
item._state.adding = True # doesn't seem to change anything
return item
def test_save(self):
self._get_item().save() # ValueError: Cannot force an update in save() with no primary key.
def test_save_force_insert(self):
self._get_item().save(force_insert=True) # SimpleItem.DoesNotExist
def test_bulk_create(self):
SimpleItem.objects.bulk_create([self._get_item()]) # SimpleItem.DoesNotExist
Possibly related: #27419, #28019.
Change History
(8)
Summary: |
Errors when trying to clone an object from a deferred queryset → Instances with deferred fields cannot be used for copying.
|
Triage Stage: |
Unreviewed → Accepted
|
Type: |
Bug → Cleanup/optimization
|
Owner: |
changed from nobody to Kuldeep Pisda
|
Status: |
new → assigned
|
Owner: |
changed from Kuldeep Pisda to Simon Charette
|
Triage Stage: |
Accepted → Ready for checkin
|
Resolution: |
→ fixed
|
Status: |
assigned → closed
|
Thanks for the report. Instances with deferred fields cannot be used for copying model instances, because "When calling save() for instances with deferred fields, only the loaded fields will be saved" (see docs). It's niche and I don't think it's worth changing, or even if it's feasible with backward compatibility, we can add a warning to the "Copying model instances" section, e.g.
Instances with deferred fields cannot be used ....
.