Repository: django/django
File: django/core/serializers/xml_serializer.py (Python)

Code before:
        self.xml.startDocument()
        self.xml.startElement("django-objects", {"version": "1.0"})

    def end_serialization(self):
        """
        End serialization -- end the document.
        """
        self.indent(0)
        self.xml.endElement("django-objects")
        self.xml.endDocument()

    def start_object(self, obj):
        """
        Called as each object is handled.
        """
        if not hasattr(obj, "_meta"):
            raise base.SerializationError(
                "Non-model object (%s) encountered during serialization" % type(obj)
            )

        self.indent(1)
        attrs = {"model": str(obj._meta)}

        pk_included = True

        if self.use_natural_primary_keys:
            natural_key_func = getattr(obj, "natural_key", None)

            if callable(natural_key_func):
                natural_key_value = None
                try:
                    natural_key_value = natural_key_func()
                except Exception:
                    pass

                is_pk_tuple = natural_key_value == (obj.pk,)

                is_opt_out = (
                    natural_key_value is None
                    or not natural_key_value
                    or is_pk_tuple
                    or not isinstance(natural_key_value, tuple)
                )

                if not is_opt_out:
                    pk_included = False

        if pk_included:
            obj_pk = obj.pk
            if obj_pk is not None:
                attrs["pk"] = obj._meta.pk.value_to_string(obj)

Review comment (refactor):
The duplication here is starting to show that we should factor out a helper as I mused on the ticket :-)

Code after:
        if original_fn and not module_helper_was_lambda:
            minidom._in_document = original_fn


class Serializer(base.Serializer):
    """Serialize a QuerySet to XML."""

    def indent(self, level):
        if self.options.get("indent") is not None:
            self.xml.ignorableWhitespace(
                "\n" + " " * self.options.get("indent") * level
            )

    def start_serialization(self):
        """
        Start serialization -- open the XML document and the root element.
        """
        self.xml = SimplerXMLGenerator(
            self.stream, self.options.get("encoding", settings.DEFAULT_CHARSET)
        )
        self.xml.startDocument()
        self.xml.startElement("django-objects", {"version": "1.0"})

    def end_serialization(self):
        """
        End serialization -- end the document.
        """
        self.indent(0)
        self.xml.endElement("django-objects")
        self.xml.endDocument()

    def start_object(self, obj):
        """
        Called as each object is handled.
        """
        if not hasattr(obj, "_meta"):
            raise base.SerializationError(
                "Non-model object (%s) encountered during serialization" % type(obj)
            )

        self.indent(1)
        attrs = {"model": str(obj._meta)}
        if not self.use_natural_primary_keys or not self._resolve_natural_key(obj):
            obj_pk = obj.pk
            if obj_pk is not None:
                attrs["pk"] = obj._meta.pk.value_to_string(obj)

        self.xml.startElement("object", attrs)

    def end_object(self, obj):
        """