def publish_changes(self, dry_run=False, all_published=None, parent=None):
    "\n        publish changes to the model - basically copy all of it's content to another copy in the \n        database.\n        if you set dry_run=True nothing will be written to the database.  combined with\n        the all_published value one can therefore get information about what other models\n        would be affected by this function\n        "
    assert (not self.is_public), 'Cannot publish public model - publish should be called from draft model'
    assert (self.pk is not None), 'Please save model before publishing'
    if (all_published is None):
        all_published = NestedSet()
    if (self in all_published):
        return all_published.original(self).public
    all_published.add(self, parent=parent)
    self._pre_publish(dry_run, all_published)
    public_version = self.public
    if (not public_version):
        public_version = self.__class__(is_public=True)
    excluded_fields = self.PublishMeta.excluded_fields()
    reverse_fields_to_publish = self.PublishMeta.reverse_fields_to_publish()
    if self._changes_need_publishing():
        for field in self._meta.fields:
            if (field.name in excluded_fields):
                continue
            value = getattr(self, field.name)
            if isinstance(field, RelatedField):
                related = field.rel.to
                if issubclass(related, Publishable):
                    if (value is not None):
                        value = value._get_public_or_publish(dry_run=dry_run, all_published=all_published, parent=self)
            if (not dry_run):
                publish_function = self.PublishMeta.find_publish_function(field.name, setattr)
                publish_function(public_version, field.name, value)
        if (not dry_run):
            public_version.save()
            self.public = public_version
            self.publish_state = Publishable.PUBLISH_DEFAULT
            self.save(mark_changed=False)
    for field in self._meta.many_to_many:
        name = field.name
        if (name in excluded_fields):
            continue
        m2m_manager = getattr(self, name)
        public_objs = list(m2m_manager.all())
        (field_object, model, direct, m2m) = self._meta.get_field_by_name(name)
        through_model = self._get_through_model(field_object)
        if through_model:
            if issubclass(through_model, Publishable):
                m2m_reverse_name = field_object.m2m_reverse_name()
                for reverse_field in through_model._meta.fields:
                    if (reverse_field.column == m2m_reverse_name):
                        related_name = reverse_field.name
                        related_field = getattr(through_model, related_name).field
                        reverse_name = related_field.related.get_accessor_name()
                        reverse_fields_to_publish.append(reverse_name)
                        break
                continue
        related = field_object.rel.to
        if issubclass(related, Publishable):
            public_objs = [p._get_public_or_publish(dry_run=dry_run, all_published=all_published, parent=self) for p in public_objs]
        if (not dry_run):
            public_m2m_manager = getattr(public_version, name)
            old_objs = public_m2m_manager.exclude(pk__in=[p.pk for p in public_objs])
            public_m2m_manager.remove(*old_objs)
            public_m2m_manager.add(*public_objs)
    for obj in self._meta.get_all_related_objects():
        if issubclass(obj.model, Publishable):
            name = obj.get_accessor_name()
            if (name in excluded_fields):
                continue
            if (name not in reverse_fields_to_publish):
                continue
            if obj.field.rel.multiple:
                related_items = getattr(self, name).all()
            else:
                try:
                    related_items = [getattr(self, name)]
                except obj.model.DoesNotExist:
                    related_items = []
            for related_item in related_items:
                related_item.publish(dry_run=dry_run, all_published=all_published, parent=self)
            if (self.public and (not dry_run)):
                if obj.field.rel.multiple:
                    public_ids = [r.public_id for r in related_items]
                    deleted_items = getattr(self.public, name).exclude(pk__in=public_ids)
                    deleted_items.delete(mark_for_deletion=False)
    self._post_publish(dry_run, all_published)
    return public_version
publish changes to the model - basically copy all of it's content to another copy in the 
database.
if you set dry_run=True nothing will be written to the database.  combined with
the all_published value one can therefore get information about what other models
would be affected by this function
def publish_changes(self, dry_run=False, all_published=None, parent=None):
    "\n        publish changes to the model - basically copy all of it's content to another copy in the \n        database.\n        if you set dry_run=True nothing will be written to the database.  combined with\n        the all_published value one can therefore get information about what other models\n        would be affected by this function\n        "
    assert (not self.is_public), 'Cannot publish public model - publish should be called from draft model'
    assert (self.pk is not None), 'Please save model before publishing'
    if (all_published is None):
        all_published = NestedSet()
    if (self in all_published):
        return all_published.original(self).public
    all_published.add(self, parent=parent)
    self._pre_publish(dry_run, all_published)
    public_version = self.public
    if (not public_version):
        public_version = self.__class__(is_public=True)
    excluded_fields = self.PublishMeta.excluded_fields()
    reverse_fields_to_publish = self.PublishMeta.reverse_fields_to_publish()
    if self._changes_need_publishing():
        for field in self._meta.fields:
            if (field.name in excluded_fields):
                continue
            value = getattr(self, field.name)
            if isinstance(field, RelatedField):
                related = field.rel.to
                if issubclass(related, Publishable):
                    if (value is not None):
                        value = value._get_public_or_publish(dry_run=dry_run, all_published=all_published, parent=self)
            if (not dry_run):
                publish_function = self.PublishMeta.find_publish_function(field.name, setattr)
                publish_function(public_version, field.name, value)
        if (not dry_run):
            public_version.save()
            self.public = public_version
            self.publish_state = Publishable.PUBLISH_DEFAULT
            self.save(mark_changed=False)
    for field in self._meta.many_to_many:
        name = field.name
        if (name in excluded_fields):
            continue
        m2m_manager = getattr(self, name)
        public_objs = list(m2m_manager.all())
        (field_object, model, direct, m2m) = self._meta.get_field_by_name(name)
        through_model = self._get_through_model(field_object)
        if through_model:
            if issubclass(through_model, Publishable):
                m2m_reverse_name = field_object.m2m_reverse_name()
                for reverse_field in through_model._meta.fields:
                    if (reverse_field.column == m2m_reverse_name):
                        related_name = reverse_field.name
                        related_field = getattr(through_model, related_name).field
                        reverse_name = related_field.related.get_accessor_name()
                        reverse_fields_to_publish.append(reverse_name)
                        break
                continue
        related = field_object.rel.to
        if issubclass(related, Publishable):
            public_objs = [p._get_public_or_publish(dry_run=dry_run, all_published=all_published, parent=self) for p in public_objs]
        if (not dry_run):
            public_m2m_manager = getattr(public_version, name)
            old_objs = public_m2m_manager.exclude(pk__in=[p.pk for p in public_objs])
            public_m2m_manager.remove(*old_objs)
            public_m2m_manager.add(*public_objs)
    for obj in self._meta.get_all_related_objects():
        if issubclass(obj.model, Publishable):
            name = obj.get_accessor_name()
            if (name in excluded_fields):
                continue
            if (name not in reverse_fields_to_publish):
                continue
            if obj.field.rel.multiple:
                related_items = getattr(self, name).all()
            else:
                try:
                    related_items = [getattr(self, name)]
                except obj.model.DoesNotExist:
                    related_items = []
            for related_item in related_items:
                related_item.publish(dry_run=dry_run, all_published=all_published, parent=self)
            if (self.public and (not dry_run)):
                if obj.field.rel.multiple:
                    public_ids = [r.public_id for r in related_items]
                    deleted_items = getattr(self.public, name).exclude(pk__in=public_ids)
                    deleted_items.delete(mark_for_deletion=False)
    self._post_publish(dry_run, all_published)
    return public_version