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

Code before:

    def getvalue(self):
        """
        Return the fully serialized queryset (or None if the output stream is
        not seekable).
        """
        if callable(getattr(self.stream, "getvalue", None)):
            return self.stream.getvalue()

    def _should_include_pk(self, obj):
        """
        Determines whether the Primary Key (PK) should be included in the
        serialized data for the given object, especially when
        use_natural_primary_keys=True is set.
        """
        if not self.use_natural_primary_keys:
            return True

        return not self._resolve_natural_key(obj)

    def _resolve_fk_natural_key(self, obj, field):
        """
        Return the natural key for a ForeignKey's related object when valid.

        When natural foreign keys are enabled, the helper attempts to use the
        related object's natural key; otherwise it falls back to the PK.
        """
        if not self.use_natural_foreign_keys:
            return None

        if not self._model_supports_natural_key(field.remote_field.model):
            return None

        related = getattr(obj, field.name, None)
        return self._resolve_natural_key(related)

    def _resolve_natural_key(self, obj):
        """
        Return a natural key tuple for the given object when available.
        """
        if not (obj and callable(getattr(obj, "natural_key", None))):
            return None

        natural_key_value = obj.natural_key()
        if not natural_key_value:
            return None

        return natural_key_value

    def _model_supports_natural_key(self, model):
        """Return True if the model class exposes a callable natural_key()."""

Review comment (refactor):
I'm not seeing where this fallback behavior is implemented. I'll take a quick stab at simplifying the helpers a little further.

Code after:

    def getvalue(self):
        """
        Return the fully serialized queryset (or None if the output stream is
        not seekable).
        """
        if callable(getattr(self.stream, "getvalue", None)):
            return self.stream.getvalue()

    def _resolve_natural_key(self, obj):
        """Return a natural key tuple for the given object when available."""
        try:
            return obj.natural_key()
        except AttributeError:
            return None

    def _resolve_fk_natural_key(self, obj, field):
        """
        Return the natural key for a ForeignKey's related object, or None if
        not supported.
        """
        if not self._model_supports_natural_key(field.remote_field.model):
            return None

        related = getattr(obj, field.name, None)
        try:
            return related.natural_key()
        except AttributeError:
            return None

    def _model_supports_natural_key(self, model):
        """Return True if the model defines a natural_key() method."""
        try:
            return callable(model.natural_key)
        except AttributeError:
            return False


class Deserializer:
    """
    Abstract base deserializer class.
    """

    def __init__(self, stream_or_string, **options):
        """
        Init this serializer given a stream or a string
        """
        self.options = options
        if isinstance(stream_or_string, str):
            self.stream = StringIO(stream_or_string)
        else: