diff --git a/openwisp_controller/geo/models.py b/openwisp_controller/geo/models.py index 3e0d3240e..581de9d54 100644 --- a/openwisp_controller/geo/models.py +++ b/openwisp_controller/geo/models.py @@ -1,4 +1,7 @@ from django.contrib.gis.db import models +from django.contrib.gis.geos import Point +from django.core.exceptions import ValidationError +from django.utils.translation import ugettext_lazy as _ from django_loci.base.models import AbstractFloorPlan, AbstractLocation, AbstractObjectLocation from openwisp_users.mixins import OrgMixin, ValidateOrgMixin @@ -8,6 +11,11 @@ class Location(OrgMixin, AbstractLocation): class Meta(AbstractLocation.Meta): abstract = False + def clean(self): + if self.geometry is not None and not isinstance(self.geometry, Point): + raise ValidationError({'geometry': _('Only point geometry is allowed')}) + super().clean() + class FloorPlan(OrgMixin, AbstractFloorPlan): location = models.ForeignKey(Location, models.CASCADE) diff --git a/openwisp_controller/geo/tests/test_models.py b/openwisp_controller/geo/tests/test_models.py index 848b58a08..5e019abb5 100644 --- a/openwisp_controller/geo/tests/test_models.py +++ b/openwisp_controller/geo/tests/test_models.py @@ -1,3 +1,4 @@ +from django.contrib.gis.geos import LineString, Point, Polygon from django.core.exceptions import ValidationError from django.test import TestCase from django_loci.tests.base.test_models import BaseTestModels @@ -23,3 +24,21 @@ def test_floorplan_location_validation(self): self.assertIn('location', e.message_dict) else: self.fail('ValidationError not raised') + + def test_add_location_with_point_geometry(self): + self._create_location(geometry=Point(0, 0, srid=4326), name='point') + obj = self.location_model.objects.get(name='point') + self.assertEqual(obj.name, 'point') + + def test_add_location_with_line_geometry(self): + with self.assertRaisesMessage(ValidationError, 'Only point geometry is allowed'): + self._create_location(geometry=LineString((0, 0), (1, 1), srid=4326), name='line') + obj = self.location_model.objects.filter(name='line') + self.assertEqual(obj.count(), 0) + + def tes_add_location_with_polygon_geometry(self): + with self.assertRaisesMessage(ValidationError, 'Only point geometry is allowed'): + poly = Polygon((0, 0), (0, 1), (1, 1), (1, 0), (0, 0), srid=4326) + self._create_location(geometry=poly, name='poly') + obj = self.location_model.objects.filter(name='poly') + self.assertEqual(obj.count(), 0)