Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refs #23804 -- RasterField initialization only if HAS_GDAL #4905

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 9 additions & 1 deletion 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
Expand Down Expand Up @@ -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:
Expand All @@ -426,6 +431,9 @@ def get_db_prep_value(self, value, connection, prepared=False):

def contribute_to_class(self, cls, name, **kwargs):
super(RasterField, self).contribute_to_class(cls, name, **kwargs)
# For systems without gdal, importing GDALRaster would raise an
# exception, so it can only be imported here.
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
Expand Down
3 changes: 2 additions & 1 deletion django/contrib/gis/gdal/__init__.py
Expand Up @@ -53,7 +53,8 @@
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
Expand Down
13 changes: 9 additions & 4 deletions tests/gis_tests/models.py
Expand Up @@ -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 exception raised without GDAL
models.OriginalRasterField = models.RasterField
except ImproperlyConfigured:
models.GeoManager = models.Manager
models.GeometryField = DummyField
Expand All @@ -21,3 +21,8 @@ def __init__(self, dim=None, srid=None, geography=None, spatial_index=True, *arg
models.PointField = DummyField
models.PolygonField = DummyField
models.RasterField = DummyField

try:
models.RasterField()
except ImproperlyConfigured:
models.RasterField = DummyField
2 changes: 1 addition & 1 deletion tests/gis_tests/rasterapp/models.py
Expand Up @@ -2,7 +2,7 @@


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']
Expand Down
24 changes: 23 additions & 1 deletion 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


Expand Down Expand Up @@ -70,3 +74,21 @@ def test_implicit_raster_transformation(self):
[-87.9298551266551, 9.459646421449934e-06, 0.0,
23.94249275457565, 0.0, -9.459646421449934e-06]
)

def test_verbose_name_arg(self):
"""
Test if the positional verbose name argument is accepted.
"""
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()