4

How does one update - in bulk - a many to many field in the queryset of a Django data model?

For instance, I have a data model called Photo, and another called PhotoStream. In Photo, I have which_stream = models.ManyToManyField(PhotoStream).

I extracted a queryset of Photos called childhood_photos, and I need to add a new PhotoStream object in the many-to-many fields of all objects within this queryset. Let's call this PhotoStream object for_classmates.

I try childhood_photos.update(which_stream.add(for_classmates)), but it gives me an error: global name 'which_stream' is not defined.

How can I do this operation?

Hassan Baig
  • 15,055
  • 27
  • 102
  • 205

1 Answers1

10

You can access the through model of your m2n relationship via the field's .through attribute (see the documentation). That will allow you to bulk create the necessary through model instances:

through_model = Photo.which_stream.through  # gives you access to auto-created through model
# print through_model
# <class 'app_label.models.Photo_which_stream'>  # or sth. similar

through_model.objects.bulk_create([
    through_model(photo_id=pk, photostream_id=for_classmates.pk) 
        for pk in childhood_photos.values_list('pk', flat=True)
])
user2390182
  • 72,016
  • 6
  • 67
  • 89
  • 1
    Thanks for this. By the looks of this, this is **creating** new fields, but solely in the `through` table. To my mind, that's what the **update** procedure I was trying does too. Hence they're equivalent. Wanted to confirm I have it correct in my head, yes? – Hassan Baig Apr 24 '16 at 17:42
  • What do you mean by 'solely in the through table'? The through table is the ONLY place where anything ever really happens for a `ManyToManyField`! This is not creating new fields (!?), but adds the for_classmates` stream to all the desired photos. – user2390182 Apr 24 '16 at 17:50
  • 1
    Using `update` operation only updates the fields which are on that particular model. The thing about M2M fields are that they are not actually created in the particular table but a new through table is created in the database relating your first and second table. So doing `update` in `Photo` model for updating streams is not same as creating rows in through table. – AKS Apr 25 '16 at 05:30