Add multiple entries to many-to-many field with different through_defaults for each entry

Say I have a model A with a field called m2m which is a many-to-many field to another model B.

Then I want to add all the elements inside a queryset to this field at once. If qs is my queryset, I could do a.m2m.add(*qs). However, say I’m using a through model for the relationship and that through model has a custom field ordering.

Is there any way I can add the whole queryset to my m2m field in a single instruction, while specifying a different value for the field ordering for each entry I’m adding? I know what for a single entry you can use through_defaults, but I haven’t been able to find anything for bulk creation.

I could surely do:

count = 0
for e in qs:
    a.m2m.add(e, through_defaults={'ordering': count})
    count += 1

But it’s not very elegant.

Is there a way to achieve it like I mentioned above? Thank you!

Your “through” table is a table - it has at least three columns in this case, the foreign keys to the two tables and the field ordering.

You can work with this table the same way you work with any other table.

This means you can create individual rows the same way you create rows in any other table.

For example:

through_row = ThroughTable(a=some_a, b=some_b, ordering=count)

And you can get as fancy with that as you wish.

Thank you. I guess what I was after was a more “elegant” way of doing this. For example, had I not had the requirement of having extra fields in the through table, I could have just done it in a one liner with some_a.m2mfield.add(*qs), but apparently there is no such way of doing anything like that in this case.