Fixed #25011, Refs #23804 -- Added check for GDAL on RasterField initialization

This commit is contained in:
Daniel Wiesmann 2015-06-23 20:39:18 +01:00 committed by Tim Graham
parent 4202959b6f
commit c0fff64486
5 changed files with 43 additions and 8 deletions

View File

@ -1,7 +1,7 @@
from django.contrib.gis import forms from django.contrib.gis import forms
from django.contrib.gis.db.models.lookups import gis_lookups from django.contrib.gis.db.models.lookups import gis_lookups
from django.contrib.gis.db.models.proxy import SpatialProxy 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.contrib.gis.geometry.backend import Geometry, GeometryException
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.db.models.expressions import Expression from django.db.models.expressions import Expression
@ -405,6 +405,11 @@ class RasterField(BaseSpatialField):
description = _("Raster Field") description = _("Raster Field")
geom_type = 'RASTER' 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): def _check_connection(self, connection):
# Make sure raster fields are used only on backends with raster support. # Make sure raster fields are used only on backends with raster support.
if not connection.features.gis_enabled or not connection.features.supports_raster: 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): def contribute_to_class(self, cls, name, **kwargs):
super(RasterField, self).contribute_to_class(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 # Setup for lazy-instantiated Raster object. For large querysets, the
# instantiation of all GDALRasters can potentially be expensive. This # instantiation of all GDALRasters can potentially be expensive. This
# delays the instantiation of the objects to the moment of evaluation # delays the instantiation of the objects to the moment of evaluation

View File

@ -53,7 +53,8 @@ try:
HAS_GDAL = True HAS_GDAL = True
__all__ += [ __all__ += [
'Driver', 'DataSource', 'gdal_version', 'gdal_full_version', 'Driver', 'DataSource', 'gdal_version', 'gdal_full_version',
'GDAL_VERSION', 'SpatialReference', 'CoordTransform', 'OGRGeometry', 'GDALRaster', 'GDAL_VERSION', 'SpatialReference', 'CoordTransform',
'OGRGeometry',
] ]
except GDALException: except GDALException:
HAS_GDAL = False HAS_GDAL = False

View File

@ -6,12 +6,12 @@ class DummyField(models.Field):
def __init__(self, dim=None, srid=None, geography=None, spatial_index=True, *args, **kwargs): def __init__(self, dim=None, srid=None, geography=None, spatial_index=True, *args, **kwargs):
super(DummyField, self).__init__(*args, **kwargs) super(DummyField, self).__init__(*args, **kwargs)
try: try:
from django.contrib.gis.db import models from django.contrib.gis.db import models
try: # Store a version of the original raster field for testing the exception
models.RasterField() # raised if GDAL isn't installed.
except ImproperlyConfigured: models.OriginalRasterField = models.RasterField
models.RasterField = DummyField
except ImproperlyConfigured: except ImproperlyConfigured:
models.GeoManager = models.Manager models.GeoManager = models.Manager
models.GeometryField = DummyField models.GeometryField = DummyField
@ -21,3 +21,8 @@ except ImproperlyConfigured:
models.PointField = DummyField models.PointField = DummyField
models.PolygonField = DummyField models.PolygonField = DummyField
models.RasterField = DummyField models.RasterField = DummyField
try:
models.RasterField()
except ImproperlyConfigured:
models.RasterField = DummyField

View File

@ -2,7 +2,7 @@ from ..models import models
class RasterModel(models.Model): 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: class Meta:
required_db_features = ['supports_raster'] required_db_features = ['supports_raster']

View File

@ -1,9 +1,13 @@
import json import json
from unittest import skipIf
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.shortcuts import numpy 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 ..data.rasters.textrasters import JSON_RASTER
from ..models import models
from .models import RasterModel from .models import RasterModel
@ -70,3 +74,21 @@ class RasterFieldTest(TransactionTestCase):
[-87.9298551266551, 9.459646421449934e-06, 0.0, [-87.9298551266551, 9.459646421449934e-06, 0.0,
23.94249275457565, 0.0, -9.459646421449934e-06] 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()