From 1b7623fdfd8d4157b03126006f23f74f4ef6255c Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Thu, 4 Jun 2020 09:25:39 -0400 Subject: [PATCH] Refs #30446 -- Defined output_field of BoundingCircle() GIS database function. This prevented the default behavior of BaseExpression._resolve_output_field from error'ing out when such functions accepted both expressions from mixed types (e.g. BoundingCircle(Polygon, num_seg=12)). --- django/contrib/gis/db/models/functions.py | 2 +- tests/gis_tests/geoapp/test_functions.py | 27 ++++++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/django/contrib/gis/db/models/functions.py b/django/contrib/gis/db/models/functions.py index debd859390..8ab5de6db7 100644 --- a/django/contrib/gis/db/models/functions.py +++ b/django/contrib/gis/db/models/functions.py @@ -223,7 +223,7 @@ class AsWKT(GeoFunc): arity = 1 -class BoundingCircle(OracleToleranceMixin, GeoFunc): +class BoundingCircle(OracleToleranceMixin, GeomOutputGeoFunc): def __init__(self, expression, num_seg=48, **extra): super().__init__(expression, num_seg, **extra) diff --git a/tests/gis_tests/geoapp/test_functions.py b/tests/gis_tests/geoapp/test_functions.py index c31d2f561e..c2e06db4c5 100644 --- a/tests/gis_tests/geoapp/test_functions.py +++ b/tests/gis_tests/geoapp/test_functions.py @@ -9,7 +9,7 @@ from django.contrib.gis.geos import ( ) from django.contrib.gis.measure import Area from django.db import NotSupportedError, connection -from django.db.models import Sum, Value +from django.db.models import IntegerField, Sum, Value from django.test import TestCase, skipUnlessDBFeature from ..utils import FuncTestMixin, mariadb, mysql, oracle, postgis, spatialite @@ -194,16 +194,21 @@ class GISFunctionsTests(FuncTestMixin, TestCase): self.assertEqual(qs[0].circle.num_points, circle_num_points(48)) self.assertEqual(qs[1].circle.num_points, circle_num_points(48)) - qs = Country.objects.annotate(circle=functions.BoundingCircle('mpoly', num_seg=12)).order_by('name') - if postgis: - self.assertGreater(qs[0].circle.area, 168.4, 0) - self.assertLess(qs[0].circle.area, 169.5, 0) - self.assertAlmostEqual(qs[1].circle.area, 136, 0) - self.assertEqual(qs[0].circle.num_points, circle_num_points(12)) - self.assertEqual(qs[1].circle.num_points, circle_num_points(12)) - else: - self.assertAlmostEqual(qs[0].circle.area, expected_areas[0], 0) - self.assertAlmostEqual(qs[1].circle.area, expected_areas[1], 0) + tests = [12, Value(12, output_field=IntegerField())] + for num_seq in tests: + with self.subTest(num_seq=num_seq): + qs = Country.objects.annotate( + circle=functions.BoundingCircle('mpoly', num_seg=num_seq), + ).order_by('name') + if postgis: + self.assertGreater(qs[0].circle.area, 168.4, 0) + self.assertLess(qs[0].circle.area, 169.5, 0) + self.assertAlmostEqual(qs[1].circle.area, 136, 0) + self.assertEqual(qs[0].circle.num_points, circle_num_points(12)) + self.assertEqual(qs[1].circle.num_points, circle_num_points(12)) + else: + self.assertAlmostEqual(qs[0].circle.area, expected_areas[0], 0) + self.assertAlmostEqual(qs[1].circle.area, expected_areas[1], 0) @skipUnlessDBFeature("has_Centroid_function") def test_centroid(self):