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

Code before:
        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.
        """
        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 = natural_key_func()

                is_opt_out = not natural_key_value or not isinstance(
                    natural_key_value, tuple
                )

                if not is_opt_out:
                    pk_included = False

        return pk_included


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:
            self.stream = stream_or_string

    def __iter__(self):
        return self

    def __next__(self):
        """Iteration interface -- return the next item in the stream"""
        raise NotImplementedError(
            "subclasses of Deserializer must provide a __next__() method"

Review comment (suggestion):
Could this logic be flipped around and cleaned up w/ Demorgan's Law?

```
if callable(natural_key_func):
    natural_key_value = natural_key_func()
    if natural_key_value and isinstance(natural_key_value, tuple):
        pk_included = False
```

Code after:
        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:
            self.stream = stream_or_string

    def __iter__(self):
        return self