diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index 5cdb81e440..12be7682ed 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -1,7 +1,7 @@ from django.contrib.gis import forms from django.contrib.gis.db.models.lookups import gis_lookups from django.contrib.gis.db.models.proxy import SpatialProxy -from django.contrib.gis.gdal.raster.source import GDALRaster +from django.contrib.gis.gdal import HAS_GDAL from django.contrib.gis.geometry.backend import Geometry, GeometryException from django.core.exceptions import ImproperlyConfigured from django.db.models.expressions import Expression @@ -405,6 +405,11 @@ class RasterField(BaseSpatialField): description = _("Raster Field") geom_type = 'RASTER' + def __init__(self, *args, **kwargs): + if not HAS_GDAL: + raise ImproperlyConfigured('RasterField requires GDAL.') + super(RasterField, self).__init__(*args, **kwargs) + def _check_connection(self, connection): # Make sure raster fields are used only on backends with raster support. if not connection.features.gis_enabled or not connection.features.supports_raster: @@ -426,6 +431,8 @@ class RasterField(BaseSpatialField): def contribute_to_class(self, cls, name, **kwargs): super(RasterField, self).contribute_to_class(cls, name, **kwargs) + # Importing GDALRaster raises an exception on systems without gdal. + from django.contrib.gis.gdal import GDALRaster # Setup for lazy-instantiated Raster object. For large querysets, the # instantiation of all GDALRasters can potentially be expensive. This # delays the instantiation of the objects to the moment of evaluation diff --git a/django/contrib/gis/gdal/__init__.py b/django/contrib/gis/gdal/__init__.py index ff6ed7efcf..d356a17f09 100644 --- a/django/contrib/gis/gdal/__init__.py +++ b/django/contrib/gis/gdal/__init__.py @@ -53,7 +53,8 @@ try: HAS_GDAL = True __all__ += [ 'Driver', 'DataSource', 'gdal_version', 'gdal_full_version', - 'GDAL_VERSION', 'SpatialReference', 'CoordTransform', 'OGRGeometry', + 'GDALRaster', 'GDAL_VERSION', 'SpatialReference', 'CoordTransform', + 'OGRGeometry', ] except GDALException: HAS_GDAL = False diff --git a/tests/gis_tests/models.py b/tests/gis_tests/models.py index f5c694e688..c157258845 100644 --- a/tests/gis_tests/models.py +++ b/tests/gis_tests/models.py @@ -6,12 +6,12 @@ class DummyField(models.Field): def __init__(self, dim=None, srid=None, geography=None, spatial_index=True, *args, **kwargs): super(DummyField, self).__init__(*args, **kwargs) + try: from django.contrib.gis.db import models - try: - models.RasterField() - except ImproperlyConfigured: - models.RasterField = DummyField + # Store a version of the original raster field for testing the exception + # raised if GDAL isn't installed. + models.OriginalRasterField = models.RasterField except ImproperlyConfigured: models.GeoManager = models.Manager models.GeometryField = DummyField @@ -21,3 +21,8 @@ except ImproperlyConfigured: models.PointField = DummyField models.PolygonField = DummyField models.RasterField = DummyField + +try: + models.RasterField() +except ImproperlyConfigured: + models.RasterField = DummyField diff --git a/tests/gis_tests/rasterapp/models.py b/tests/gis_tests/rasterapp/models.py index d7cc4d15e2..4f172d4470 100644 --- a/tests/gis_tests/rasterapp/models.py +++ b/tests/gis_tests/rasterapp/models.py @@ -2,7 +2,7 @@ from ..models import models class RasterModel(models.Model): - rast = models.RasterField(null=True, srid=4326, spatial_index=True, blank=True) + rast = models.RasterField('A Verbose Raster Name', null=True, srid=4326, spatial_index=True, blank=True) class Meta: required_db_features = ['supports_raster'] diff --git a/tests/gis_tests/rasterapp/test_rasterfield.py b/tests/gis_tests/rasterapp/test_rasterfield.py index 7b4413ae0d..d1c015f499 100644 --- a/tests/gis_tests/rasterapp/test_rasterfield.py +++ b/tests/gis_tests/rasterapp/test_rasterfield.py @@ -1,9 +1,13 @@ import json +from unittest import skipIf +from django.contrib.gis.gdal import HAS_GDAL from django.contrib.gis.shortcuts import numpy -from django.test import TransactionTestCase, skipUnlessDBFeature +from django.core.exceptions import ImproperlyConfigured +from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature from ..data.rasters.textrasters import JSON_RASTER +from ..models import models from .models import RasterModel @@ -70,3 +74,21 @@ class RasterFieldTest(TransactionTestCase): [-87.9298551266551, 9.459646421449934e-06, 0.0, 23.94249275457565, 0.0, -9.459646421449934e-06] ) + + def test_verbose_name_arg(self): + """ + RasterField should accept a positional verbose name argument. + """ + self.assertEqual( + RasterModel._meta.get_field('rast').verbose_name, + 'A Verbose Raster Name' + ) + + +@skipIf(HAS_GDAL, 'Test raster field exception on systems without GDAL.') +class RasterFieldWithoutGDALTest(TestCase): + + def test_raster_field_without_gdal_exception(self): + msg = 'RasterField requires GDAL.' + with self.assertRaisesMessage(ImproperlyConfigured, msg): + models.OriginalRasterField()