docs: def handle_publishable_m2m_changed(
          sender, instance, action, reverse, model, pk_set, **kwargs):
      """
      Cache related published objects in `pre_clear` so they can be restored in
      `post_clear`.
      """
      # Do nothing if the target model is not publishable.
      if not issubclass(model, PublishingModel):
          return
      # Get the right `ManyRelatedManager`. Iterate M2Ms and compare `sender`
      # (the through model), in case there are multiple M2Ms to the same model.
      if reverse:
          for rel_obj in instance._meta.get_all_related_many_to_many_objects():
              if rel_obj.field.rel.through == sender:
                  m2m = getattr(instance, rel_obj.get_accessor_name())
                  break
      else:
          for field in instance._meta.many_to_many:
              if field.rel.through == sender:
                  m2m = getattr(instance, field.attname)
                  break
      # Cache published PKs on the instance.
      if action == 'pre_clear':
          instance._published_m2m_cache = set(
              m2m.filter(publishing_is_draft=False).values_list('pk', flat=True))
      # Add published PKs from the cache.
      if action == 'post_clear':
          m2m.add(*instance._published_m2m_cache)
          del instance._published_m2m_cache