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

Code before:
                    self.xml.endElement("natural")
            else:
                self.xml.characters(str(related_att))
        else:
            self.xml.addQuickElement("None")
        self.xml.endElement("field")

    def handle_m2m_field(self, obj, field):
        """
        Handle a ManyToManyField. Related objects are only serialized as
        references to the object's PK (i.e. the related *data* is not dumped,
        just the relation).
        """
        if field.remote_field.through._meta.auto_created:
            self._start_relational_field(field)

            use_natural = (
                self.use_natural_foreign_keys
                and self._model_supports_natural_key(field.remote_field.model)
            )

            if use_natural:
                # If the objects in the m2m have a natural key, use it
                def handle_m2m(value):
                    natural = self._resolve_natural_key(value)
                    if not natural:
                        self.xml.addQuickElement("object", attrs={"pk": str(value.pk)})
                        return
                    # Iterable natural keys are rolled out as subelements
                    self.xml.startElement("object", {})
                    for key_value in natural:
                        self.xml.startElement("natural", {})
                        self.xml.characters(str(key_value))
                        self.xml.endElement("natural")
                    self.xml.endElement("object")

                def queryset_iterator(obj, field):
                    attr = getattr(obj, field.name)
                    chunk_size = (
                        2000 if getattr(attr, "prefetch_cache_name", None) else None
                    )
                    return attr.iterator(chunk_size)

            else:

                def handle_m2m(value):
                    self.xml.addQuickElement("object", attrs={"pk": str(value.pk)})

                def queryset_iterator(obj, field):
                    query_set = getattr(obj, field.name).select_related(None).only("pk")
                    chunk_size = 2000 if query_set._prefetch_related_lookups else None

Review comment (refactor):
If we move this boolean test into your helper, then we can avoid adding this branch and ensure we aren't missing analogous changes for the `queryset_iterator` nested function.

Code after:
        else:
            self.xml.addQuickElement("None")

        self.xml.endElement("field")

    def handle_fk_field(self, obj, field):
        """
        Handle a ForeignKey (they need to be treated slightly
        differently from regular fields).
        """
        self._start_relational_field(field)
        related_att = getattr(obj, field.attname)
        if related_att is not None:
            if self.use_natural_foreign_keys and (
                natural_key_value := self._resolve_fk_natural_key(obj, field)
            ):
                # Iterable natural keys are rolled out as subelements
                for key_value in natural_key_value:
                    self.xml.startElement("natural", {})
                    self.xml.characters(str(key_value))
                    self.xml.endElement("natural")
            else:
                self.xml.characters(str(related_att))
        else:
            self.xml.addQuickElement("None")
        self.xml.endElement("field")

    def handle_m2m_field(self, obj, field):
        """
        Handle a ManyToManyField. Related objects are only serialized as
        references to the object's PK (i.e. the related *data* is not dumped,
        just the relation).
        """
        if field.remote_field.through._meta.auto_created:
            self._start_relational_field(field)
            if self.use_natural_foreign_keys and self._model_supports_natural_key(
                field.remote_field.model
            ):
                # If the objects in the m2m have a natural key, use it
                def handle_m2m(value):
                    if natural := self._resolve_natural_key(value):
                        # Iterable natural keys are rolled out as subelements
                        self.xml.startElement("object", {})
                        for key_value in natural:
                            self.xml.startElement("natural", {})
                            self.xml.characters(str(key_value))
                            self.xml.endElement("natural")
                        self.xml.endElement("object")
                    else:
                        self.xml.addQuickElement("object", attrs={"pk": str(value.pk)})