class IntermediatedManyToManyField(ManyToManyField): """ ManyToManyField that can be set even if it relies on a intermediary model. """ def contribute_to_class(self, cls, name): super(IntermediatedManyToManyField, self).contribute_to_class(cls, name) # Override the descriptor for the m2m relation setattr( cls, self.name, _ReverseIntermediatedManyRelatedObjectsDescriptor(self), ) class _ReverseIntermediatedManyRelatedObjectsDescriptor( ReverseManyRelatedObjectsDescriptor ): def __set__(self, instance, new_related_values): if instance is None: raise AttributeError('Manager must be accessed via instance') manager = self.__get__(instance) pre_existing_values = manager.all() new_related_value_pks = [ new_related_value.pk for new_related_value in new_related_values] values_to_unrelate = pre_existing_values.exclude( pk__in=new_related_value_pks) values_to_unrelate.delete() # Create relationships for values not previously related, leaving alone # those which exist already intermediary_model = self.field.rel.through instance_field_name = manager.source_field_name related_field_name = manager.target_field_name for related_value in new_related_values: if related_value not in pre_existing_values: intermediary_model.objects.create(**{ instance_field_name: instance, related_field_name: related_value, })