docs: def sync_deleted_attachments(self, api_post):
          """
          Remove Posts with post_type=attachment that have been removed from the given Post on the WordPress side.
  
          Logic:
          - get the list of Posts with post_type = attachment whose parent_id = this post_id
          - get the corresponding list from WP API
          - perform set difference
          - delete extra local attachments if any
  
          :param api_post: the API data for the Post
          :return: None
          """
          existing_IDs = set(Post.objects.filter(site_id=self.site_id,
                                                 post_type="attachment",
                                                 parent__icontains='"ID":{}'.format(api_post["ID"]))
                                         .values_list("wp_id", flat=True))
  
          # can't delete what we don't have
          if existing_IDs:
  
              api_IDs = set()
  
              # call the API again to the get the full list of attachment posts whose parent is this post's wp_id
              path = "sites/{}/posts/".format(self.site_id)
              params = {
                  "type": "attachment",
                  "parent_id": api_post["ID"],
                  "fields": "ID",
                  "number": 100
              }
              page = 1
  
              response = self.get(path, params)
  
              if not response.ok:
                  logger.warning("Response NOT OK! status_code=%s\n%s", response.status_code, response.text)
  
              # loop around since there may be more than 100 attachments (example: really large slideshows)
              while response.ok and response.text and page < 10:
  
                  api_json = response.json()
                  api_attachments = api_json.get("posts", [])
  
                  # iteratively extend the set to include this page's IDs
                  api_IDs |= set(a["ID"] for a in api_attachments)
  
                  # get next page
                  page += 1
                  next_page_handle = api_json.get("meta", {}).get("next_page")
                  if next_page_handle:
                      params["page_handle"] = next_page_handle
                  else:
                      # no more pages left
                      break
  
                  response = self.get(path, params)
  
                  if not response.ok:
                      logger.warning("Response NOT OK! status_code=%s\n%s", response.status_code, response.text)
                      return
  
              # perform set difference
              to_remove = existing_IDs - api_IDs
  
              # purge the extras
              if to_remove:
                  Post.objects.filter(site_id=self.site_id,
                                      post_type="attachment",
                                      parent__icontains='"ID":{}'.format(api_post["ID"]),
                                      wp_id__in=list(to_remove)).delete()