diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index 6908d20ef7..ad7b961883 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -8,6 +8,7 @@ """ import sys from decimal import Decimal, InvalidOperation as DecimalInvalidOperation +from pathlib import Path from django.contrib.gis.db.models import GeometryField from django.contrib.gis.gdal import ( @@ -93,7 +94,7 @@ class LayerMapping: argument usage. """ # Getting the DataSource and the associated Layer. - if isinstance(data, str): + if isinstance(data, (str, Path)): self.ds = DataSource(data, encoding=encoding) else: self.ds = data diff --git a/docs/ref/contrib/gis/layermapping.txt b/docs/ref/contrib/gis/layermapping.txt index cbce2aff59..15a36fa89d 100644 --- a/docs/ref/contrib/gis/layermapping.txt +++ b/docs/ref/contrib/gis/layermapping.txt @@ -142,6 +142,10 @@ Keyword Arguments Default is ``'default'``. ===================== ===================================================== +.. versionchanged:: 3.2 + + Support for :class:`pathlib.Path` ``data_source`` was added. + ``save()`` Keyword Arguments ---------------------------- diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt index 206609422d..089e0c08c4 100644 --- a/docs/releases/3.2.txt +++ b/docs/releases/3.2.txt @@ -117,6 +117,9 @@ Minor features * The :class:`~django.contrib.gis.gdal.DataSource` class now supports :class:`pathlib.Path`. +* The :class:`~django.contrib.gis.utils.LayerMapping` class now supports + :class:`pathlib.Path`. + :mod:`django.contrib.messages` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/gis_tests/layermap/tests.py b/tests/gis_tests/layermap/tests.py index 50fdb4815a..4e1d0f69ba 100644 --- a/tests/gis_tests/layermap/tests.py +++ b/tests/gis_tests/layermap/tests.py @@ -1,8 +1,8 @@ import datetime -import os import unittest from copy import copy from decimal import Decimal +from pathlib import Path from django.conf import settings from django.contrib.gis.gdal import DataSource @@ -19,12 +19,12 @@ from .models import ( has_nulls_mapping, inter_mapping, ) -shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, 'data')) -city_shp = os.path.join(shp_path, 'cities', 'cities.shp') -co_shp = os.path.join(shp_path, 'counties', 'counties.shp') -inter_shp = os.path.join(shp_path, 'interstates', 'interstates.shp') -invalid_shp = os.path.join(shp_path, 'invalid', 'emptypoints.shp') -has_nulls_geojson = os.path.join(shp_path, 'has_nulls', 'has_nulls.geojson') +shp_path = Path(__file__).resolve().parent.parent / 'data' +city_shp = shp_path / 'cities' / 'cities.shp' +co_shp = shp_path / 'counties' / 'counties.shp' +inter_shp = shp_path / 'interstates' / 'interstates.shp' +invalid_shp = shp_path / 'invalid' / 'emptypoints.shp' +has_nulls_geojson = shp_path / 'has_nulls' / 'has_nulls.geojson' # Dictionaries to hold what's expected in the county shapefile. NAMES = ['Bexar', 'Galveston', 'Harris', 'Honolulu', 'Pueblo'] @@ -83,6 +83,11 @@ class LayerMapTest(TestCase): self.assertAlmostEqual(pnt1.x, pnt2.x, 5) self.assertAlmostEqual(pnt1.y, pnt2.y, 5) + def test_data_source_str(self): + lm = LayerMapping(City, str(city_shp), city_mapping) + lm.save() + self.assertEqual(City.objects.count(), 3) + def test_layermap_strict(self): "Testing the `strict` keyword, and import of a LineString shapefile." # When the `strict` keyword is set an error encountered will force @@ -307,7 +312,7 @@ class LayerMapTest(TestCase): def test_encoded_name(self): """ Test a layer containing utf-8-encoded name """ - city_shp = os.path.join(shp_path, 'ch-city', 'ch-city.shp') + city_shp = shp_path / 'ch-city' / 'ch-city.shp' lm = LayerMapping(City, city_shp, city_mapping) lm.save(silent=True, strict=True) self.assertEqual(City.objects.count(), 1)