subclass that includes updates the basedatatypesreverse dict for geometry field types querying the geometrycolumns table to get additional metadata ogrgeomtype does not require gdal and makes it easy to convert from ogc geom type name to django field spatialite uses sfsql 1 2 offsets 1000 z 2000 m and 3000 zm to indicate the presence of higher dimensional coordinates m not yet supported by django getting any geometryfield keyword arguments that are not the default subclass that includes updates the base_data_types_reverse dict for geometry field types querying the geometry_columns table to get additional metadata ogrgeomtype does not require gdal and makes it easy to convert from ogc geom type name to django field spatialite uses sfsql 1 2 offsets 1000 z 2000 m and 3000 zm to indicate the presence of higher dimensional coordinates m not yet supported by django getting any geometryfield keyword arguments that are not the default
from django.contrib.gis.gdal import OGRGeomType
from django.db.backends.sqlite3.introspection import (
    DatabaseIntrospection,
    FlexibleFieldLookupDict,
)


class GeoFlexibleFieldLookupDict(FlexibleFieldLookupDict):
    

    base_data_types_reverse = {
        **FlexibleFieldLookupDict.base_data_types_reverse,
        "point": "GeometryField",
        "linestring": "GeometryField",
        "polygon": "GeometryField",
        "multipoint": "GeometryField",
        "multilinestring": "GeometryField",
        "multipolygon": "GeometryField",
        "geometrycollection": "GeometryField",
    }


class SpatiaLiteIntrospection(DatabaseIntrospection):
    data_types_reverse = GeoFlexibleFieldLookupDict()

    def get_geometry_type(self, table_name, description):
        with self.connection.cursor() as cursor:
            
            cursor.execute(
                "SELECT coord_dimension, srid, geometry_type "
                "FROM geometry_columns "
                "WHERE f_table_name=%s AND f_geometry_column=%s",
                (table_name, description.name),
            )
            row = cursor.fetchone()
            if not row:
                raise Exception(
                    'Could not find a geometry column for "%s"."%s"'
                    % (table_name, description.name)
                )

            
            
            ogr_type = row[2]
            if isinstance(ogr_type, int) and ogr_type > 1000:
                
                
                
                ogr_type = ogr_type % 1000 + OGRGeomType.wkb25bit
            field_type = OGRGeomType(ogr_type).django

            
            dim = row[0]
            srid = row[1]
            field_params = {}
            if srid != 4326:
                field_params["srid"] = srid
            if (isinstance(dim, str) and "Z" in dim) or dim == 3:
                field_params["dim"] = 3
        return field_type, field_params

    def get_constraints(self, cursor, table_name):
        constraints = super().get_constraints(cursor, table_name)
        cursor.execute(
            "SELECT f_geometry_column "
            "FROM geometry_columns "
            "WHERE f_table_name=%s AND spatial_index_enabled=1",
            (table_name,),
        )
        for row in cursor.fetchall():
            constraints["%s__spatial__index" % row[0]] = {
                "columns": [row[0]],
                "primary_key": False,
                "unique": False,
                "foreign_key": None,
                "check": False,
                "index": True,
            }
        return constraints