Я бы предложил переопределить сохранение, но я предполагаю, что вы используете объект django.contrib.auth.User. В этом случае вы можете сделать примерно то же самое с помощью сигнала pre_save:
def manage_domains(signal,**kwargs):
if kwargs.has_key('instance'):
instance = kwargs['instance']
else: return
old_instance = User.objects.get(pk=instance.pk)
instance_categories = instance.categories.all()
for group in old_instance.groups.all():
if group not in instance_categories:
instance.groups.clear()
pre_save.connect(manage_domains, sender=User)
Это даже не близко к эффективному решению. То, что произойдет, - то, что, когда объект User сохранен, вышеупомянутые изменения будут внесены в объект в памяти, тогда сохранение перезапишет объект в базе данных. Вы столкнулись с проблемой не только попадания в базу данных, чтобы выяснить, соответствует ли неизмененная версия объекта тому, что вы собираетесь сохранить, но и циклическим просмотром двух наборов категорий, причем оба требуют попадания в базу данных. загрузить.
Лучший способ повысить эффективность здесь - это создать подкласс самого диспетчера полей ManyToMany, потому что именно на это обращают внимание изменения, происходящие в памяти, а не просто сравнивая состояние по факту. Но это будет немного сложнее и потребует от вас отказаться от встроенного объекта User.