def _spatial_attribute(self, att, settings, field_name=None, model_att=None):
        warnings.warn(
            "The %s GeoQuerySet method is deprecated. See GeoDjango Functions "
            "documentation to find the expression-based replacement." % att,
            RemovedInDjango20Warning, stacklevel=2
        )
        # Default settings.
        settings.setdefault('desc', None)
        settings.setdefault('geom_args', ())
        settings.setdefault('geom_field', None)
        settings.setdefault('procedure_args', {})
        settings.setdefault('procedure_fmt', '%(geo_col)s')
        settings.setdefault('select_params', [])

        connection = connections[self.db]

        # Performing setup for the spatial column, unless told not to.
        if settings.get('setup', True):
            default_args, geo_field = self._spatial_setup(
                att, desc=settings['desc'], field_name=field_name,
                geo_field_type=settings.get('geo_field_type'))
            for k, v in six.iteritems(default_args):
                settings['procedure_args'].setdefault(k, v)
        else:
            geo_field = settings['geo_field']

        # The attribute to attach to the model.
        if not isinstance(model_att, six.string_types):
            model_att = att

        # Special handling for any argument that is a geometry.
        for name in settings['geom_args']:
            # Using the field's get_placeholder() routine to get any needed
            # transformation SQL.
            geom = geo_field.get_prep_value(settings['procedure_args'][name])
            params = geo_field.get_db_prep_lookup('contains', geom, connection=connection)
            geom_placeholder = geo_field.get_placeholder(geom, None, connection)

            # Replacing the procedure format with that of any needed
            # transformation SQL.
            old_fmt = '%%(%s)s' % name
            new_fmt = geom_placeholder % '%%s'
            settings['procedure_fmt'] = settings['procedure_fmt'].replace(old_fmt, new_fmt)
            settings['select_params'].extend(params)

        # Getting the format for the stored procedure.
        fmt = '%%(function)s(%s)' % settings['procedure_fmt']

        # If the result of this function needs to be converted.
        if settings.get('select_field'):
            select_field = settings['select_field']
            if connection.ops.oracle:
                select_field.empty_strings_allowed = False
        else:
            select_field = Field()

        # Finally, setting the extra selection attribute with
        # the format string expanded with the stored procedure
        # arguments.
        self.query.add_annotation(
            RawSQL(fmt % settings['procedure_args'], settings['select_params'], select_field),
            model_att)
        return self
DRY routine for calling a spatial stored procedure on a geometry column
dataset/ETHPy150Open django/django/django/contrib/gis/db/models/query.py/GeoQuerySet._spatial_attribute