def published(self, for_user=UNSET, force_exchange=False):
        """
        Transform the queryset to include published equivalents of items in it. 
        This is a combination of filtering items that are published or have 
        published versions, and exchanging (effectively the latter) for their 
        published versions.

        By default, this method will apply a filter to find published items
        where `publishing_is_draft==False`.

        If it is necessary to exchange draft items for published copies, such
        as for relationships defined in the admin that only capture draft
        targets, the exchange mechanism is triggered either by forcing it
        with `force_exchange==True` or by enabling exchange by default at
        the class level with `exchange_on_published==True`. In either case,
        this method will return only the published object copies of published
        items.

        It should be noted that Fluent's notion of "published" items is
        different from ours and is user-sensitive such that privileged users
        actually see draft items as published. To make Fluent's notion of
        published items align with ours this method also acts as a shim for our
        ``visible`` filter and will return visible items when invoked by
        Fluent's view resolution process that provides the ``for_user`` kwarg.
        """
        # Re-interpret call to `published` from within Fluent to our
        # `visible` implementation, if the `for_user` kwarg is provided by the
        # calling code with a value other than `UNSET`. We use the `UNSET` flag
        # so we can distinguish calls that actually include `for_user`.
        # NOTE: This could well come straight back to us if `visible` calls
        # `published`, but the 'for_user' value will have been stripped.
        # NOTE 2: The ``for_user`` keyword argument is a no-op for us, we
        # support it solely for compatibility with Fluent code that expects it.
        if for_user is not UNSET:
            return self.visible()

        queryset = self.all()
        if force_exchange or self.exchange_on_published:
            # Exclude any draft items without a published copy. We keep all
            # published copy items, and draft items with a published copy, so
            # result may contain both draft and published items.
            queryset = queryset.exclude(
                publishing_is_draft=True, publishing_linked=None)
            # Return only published items, exchanging draft items for their
            # published copies where necessary.
            return queryset.exchange_for_published()
        else:
            # No draft-to-published exchange requested, use simple constraint
            return queryset.filter(publishing_is_draft=False)