Alexis Alexis - 5 months ago 24
Python Question

Django: copy and update a queryset

I have the following models:

class A(models.Model):
pass

class B(models.Model):
a = models.ForeignKey(A, related_name="bs")


then I have a function where I create a new record of object
A
and I would like to copy all the related records of
B


I have done something such as

def foo(new_a, old_a):
old_a.bs.all().update(pk=None, a=new_a)


but I get the following error
ERROR - failed to write data to stream: <open file '<stdout>', mode 'w' at 0x7f207949a150>

Answer

Doing something like this

def foo(new_a, old_a):
    old_a.bs.all().update(pk=None)

will try to set pk=None on all the bs for old_a which is not what you want.

Instead you'll want to do something like:

for b in old_a.bs.all():
    b.pk = None # make sure you're not overwriting the existing record
    b.a = new_a
    b.save()

I think you should also be able to use bulk_create to do this more efficiently:

new_bs = []
for b in old_a.bs.all():
    b.pk = None # make sure you're not overwriting the existing record
    b.a = new_a
    new_bs.append(b)

B.objects.bulk_create(new_bs)