def to_dict(self):
        """Get a dictionary representation of this item, formatted for Elasticsearch"""
        out = {}

        fields = self.__class__.search_objects.mapping.properties.properties

        for key in fields:
            # TODO: What if we've mapped the property to a different name? Will we allow that?

            attribute = getattr(self, key)

            field = fields[key]

            # I believe this should take the highest priority.
            if hasattr(field, "to_es"):
                out[key] = field.to_es(attribute)

            # First we check it this is a manager, in which case we have many related objects
            elif isinstance(attribute, models.Manager):
                if issubclass(attribute.model, Indexable):
                    # TODO: We want this to have some awareness of the relevant field.
                    out[key] = [obj.to_dict() for obj in attribute.all()]
                else:
                    out[key] = list(attribute.values_list("pk", flat=True))

            elif callable(attribute):
                out[key] = attribute()

            elif isinstance(attribute, Indexable):
                out[key] = attribute.to_dict()
            else:
                out[key] = attribute

            if out[key] is None:
                del out[key]
        return out