diff --git a/docs/ref/contrib/gis/install/postgis.txt b/docs/ref/contrib/gis/install/postgis.txt index 3bebbd88101..ec56397a601 100644 --- a/docs/ref/contrib/gis/install/postgis.txt +++ b/docs/ref/contrib/gis/install/postgis.txt @@ -50,6 +50,11 @@ process. An alternative is to use a migration operation in your project:: ... ] +If you plan to use PostGIS raster functionality on PostGIS 3+, you should also +activate the ``postgis_raster`` extension. You can install the extension using +the :class:`~django.contrib.postgres.operations.CreateExtension` migration +operation, or directly by running ``CREATE EXTENSION postgis_raster;``. + GeoDjango does not currently leverage any `PostGIS topology functionality`__. If you plan to use those features at some point, you can also install the ``postgis_topology`` extension by issuing ``CREATE EXTENSION diff --git a/tests/gis_tests/gis_migrations/migrations/0001_setup_extensions.py b/tests/gis_tests/gis_migrations/migrations/0001_setup_extensions.py new file mode 100644 index 00000000000..35451b3a1e8 --- /dev/null +++ b/tests/gis_tests/gis_migrations/migrations/0001_setup_extensions.py @@ -0,0 +1,18 @@ +from django.db import connection, migrations + +if connection.features.supports_raster: + from django.contrib.postgres.operations import CreateExtension + + pg_version = connection.ops.postgis_version_tuple() + + class Migration(migrations.Migration): + # PostGIS 3+ requires postgis_raster extension. + if pg_version[1:] >= (3,): + operations = [ + CreateExtension('postgis_raster'), + ] + else: + operations = [] +else: + class Migration(migrations.Migration): + operations = [] diff --git a/tests/gis_tests/gis_migrations/migrations/0001_initial.py b/tests/gis_tests/gis_migrations/migrations/0002_create_models.py similarity index 96% rename from tests/gis_tests/gis_migrations/migrations/0001_initial.py rename to tests/gis_tests/gis_migrations/migrations/0002_create_models.py index 918b56554f3..ee1191d11e6 100644 --- a/tests/gis_tests/gis_migrations/migrations/0001_initial.py +++ b/tests/gis_tests/gis_migrations/migrations/0002_create_models.py @@ -69,4 +69,7 @@ class Migration(migrations.Migration): """ Used for gis-specific migration tests. """ + dependencies = [ + ('gis_migrations', '0001_setup_extensions'), + ] operations = ops diff --git a/tests/gis_tests/gis_migrations/test_commands.py b/tests/gis_tests/gis_migrations/test_commands.py index cc892285855..31572b1e007 100644 --- a/tests/gis_tests/gis_migrations/test_commands.py +++ b/tests/gis_tests/gis_migrations/test_commands.py @@ -36,8 +36,8 @@ class MigrateTests(TransactionTestCase): self.assertTableExists("gis_migrations_family") if connection.features.supports_raster: self.assertTableExists("gis_migrations_heatmap") - # Unmigrate everything - call_command("migrate", "gis_migrations", "zero", verbosity=0) + # Unmigrate models. + call_command("migrate", "gis_migrations", "0001", verbosity=0) # All tables are gone self.assertTableNotExists("gis_migrations_neighborhood") self.assertTableNotExists("gis_migrations_household") diff --git a/tests/gis_tests/rasterapp/migrations/0001_setup_extensions.py b/tests/gis_tests/rasterapp/migrations/0001_setup_extensions.py new file mode 100644 index 00000000000..35451b3a1e8 --- /dev/null +++ b/tests/gis_tests/rasterapp/migrations/0001_setup_extensions.py @@ -0,0 +1,18 @@ +from django.db import connection, migrations + +if connection.features.supports_raster: + from django.contrib.postgres.operations import CreateExtension + + pg_version = connection.ops.postgis_version_tuple() + + class Migration(migrations.Migration): + # PostGIS 3+ requires postgis_raster extension. + if pg_version[1:] >= (3,): + operations = [ + CreateExtension('postgis_raster'), + ] + else: + operations = [] +else: + class Migration(migrations.Migration): + operations = [] diff --git a/tests/gis_tests/rasterapp/migrations/0002_rastermodels.py b/tests/gis_tests/rasterapp/migrations/0002_rastermodels.py new file mode 100644 index 00000000000..58b742c1b24 --- /dev/null +++ b/tests/gis_tests/rasterapp/migrations/0002_rastermodels.py @@ -0,0 +1,47 @@ +from django.contrib.gis.db import models +from django.db import migrations +from django.db.models import deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('rasterapp', '0001_setup_extensions'), + ] + + operations = [ + migrations.CreateModel( + name='RasterModel', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('rast', models.fields.RasterField( + blank=True, + null=True, + srid=4326, + verbose_name='A Verbose Raster Name', + )), + ('rastprojected', models.fields.RasterField( + null=True, + srid=3086, + verbose_name='A Projected Raster Table', + )), + ('geom', models.fields.PointField(null=True, srid=4326)), + ], + options={ + 'required_db_features': ['supports_raster'], + }, + ), + migrations.CreateModel( + name='RasterRelatedModel', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('rastermodel', models.ForeignKey( + on_delete=deletion.CASCADE, + to='rasterapp.rastermodel', + )), + ], + options={ + 'required_db_features': ['supports_raster'], + }, + ), + ] diff --git a/tests/gis_tests/rasterapp/migrations/__init__.py b/tests/gis_tests/rasterapp/migrations/__init__.py new file mode 100644 index 00000000000..e69de29bb2d