Skip to content

Commit

Permalink
Merge branch 'postcode-min-gen' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
dracos committed Aug 22, 2023
2 parents db4b46a + c150516 commit 7644fec
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 29 deletions.
33 changes: 26 additions & 7 deletions mapit/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
from django.db.models.query import RawQuerySet
from django.utils.encoding import smart_str
from django.utils.functional import cached_property
from django.utils.translation import gettext as _

from mapit import countries
from mapit.geometryserialiser import GeometrySerialiser
from mapit.middleware import ViewException


def materialized():
Expand Down Expand Up @@ -44,6 +46,23 @@ def new(self):
return None
return latest[0]

def query_args(self, request, format):
try:
generation = int(request.GET.get('generation', 0))
except ValueError:
raise ViewException(format, _('Bad generation specified'), 400)
if not generation:
generation = self.current().id

try:
min_generation = int(request.GET.get('min_generation', 0))
except ValueError:
raise ViewException(format, _('Bad min_generation specified'), 400)
if not min_generation:
min_generation = generation

return generation, min_generation


class Generation(models.Model):

Expand Down Expand Up @@ -138,23 +157,23 @@ def get_queryset(self):
return super(AreaManager, self).get_queryset().select_related(
'type', 'country', 'parent_area').prefetch_related('countries')

def by_location(self, location, generation=None):
def by_location(self, location, generation=None, min_generation=None):
if generation is None:
generation = Generation.objects.current()
if min_generation is None:
min_generation = Generation.objects.current()
if not location:
return []
return Area.objects.filter(
polygons__subdivided__division__contains=location,
generation_low__lte=generation, generation_high__gte=generation
generation_low__lte=generation, generation_high__gte=min_generation
)

def by_postcode(self, postcode, generation=None):
if not generation:
generation = Generation.objects.current()
def by_postcode(self, postcode, generation, min_generation):
return list(itertools.chain(
self.by_location(postcode.location, generation),
self.by_location(postcode.location, generation, min_generation),
postcode.areas.filter(
generation_low__lte=generation, generation_high__gte=generation
generation_low__lte=generation, generation_high__gte=min_generation
)
))

Expand Down
10 changes: 7 additions & 3 deletions mapit/templates/mapit/api/postcode.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ <h3>
</dd>

<dt>{% trans "Optional query parameters" %}:</dt>
<dd>
<dd><ul><li>
{% blocktrans trimmed %}
<p><i>generation</i>, to return results from a previous generation.</p>
<i>generation</i>, to return results from a previous generation.
{% endblocktrans %}
</dd>
</li><li>
{% blocktrans trimmed %}
<i>min_generation</i>, to return results since that generation.
{% endblocktrans %}
</li></ul></dd>

{% include "mapit/api/postcode-example.html" %}
</dl>
Expand Down
13 changes: 13 additions & 0 deletions mapit/tests/test_query_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,16 @@ def test_two_countries_in_query(self):
generation_low__lte=self.active_generation.id,
) & (Q() | Q(country__code__in=['DE', 'FR']) | Q(countries__code__in=['DE', 'FR']))
)

def test_generation_manager_query_args(self):
gen, min_gen = Generation.objects.query_args(
FakeRequest({'generation': self.old_generation.id}),
'json')
self.assertEqual(gen, self.old_generation.id)
self.assertEqual(min_gen, self.old_generation.id)

gen, min_gen = Generation.objects.query_args(
FakeRequest({'min_generation': self.old_generation.id}),
'json')
self.assertEqual(min_gen, self.old_generation.id)
self.assertEqual(gen, self.active_generation.id)
23 changes: 22 additions & 1 deletion mapit/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@

class AreaViewsTest(TestCase):
def setUp(self):
self.old_generation = Generation.objects.create(
active=True,
description="Test old generation",
)
self.generation = Generation.objects.create(
active=True,
description="Test generation",
Expand Down Expand Up @@ -41,7 +45,7 @@ def setUp(self):
self.small_area_1 = Area.objects.create(
name="Small Area 1",
type=self.small_type,
generation_low=self.generation,
generation_low=self.old_generation,
generation_high=self.generation,
)

Expand All @@ -52,10 +56,19 @@ def setUp(self):
generation_high=self.generation,
)

self.small_area_3 = Area.objects.create(
name="Small Area 3",
type=self.small_type,
generation_low=self.old_generation,
generation_high=self.old_generation,
)

polygon = Polygon(((-4, 51), (-4, 52), (-3, 52), (-3, 51), (-4, 51)), srid=4326)
polygon.transform(settings.MAPIT_AREA_SRID)
self.small_shape_1 = Geometry.objects.create(
area=self.small_area_1, polygon=polygon)
self.small_shape_3 = Geometry.objects.create(
area=self.small_area_3, polygon=polygon)

polygon = Polygon(((-3, 51), (-3, 52), (-2, 52), (-2, 51), (-3, 51)), srid=4326)
polygon.transform(settings.MAPIT_AREA_SRID)
Expand Down Expand Up @@ -123,6 +136,14 @@ def test_postcode_submission(self):
response = self.client.post('/postcode/', {'pc': 'PO141NT.'}, follow=True)
self.assertRedirects(response, '/postcode/PO141NT.html')

def test_postcode_endpoint(self):
response = self.client.get('/postcode/PO141NT')
content = get_content(response)
self.assertNotIn(self.small_area_3.id, content['areas'])
response = self.client.get('/postcode/PO141NT?min_generation=1')
content = get_content(response)
self.assertIn(str(self.small_area_3.id), content['areas'])

def test_json_links(self):
id = self.big_area.id
url = '/area/%d/covers.html?type=SML' % id
Expand Down
14 changes: 1 addition & 13 deletions mapit/views/areas.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,7 @@ def output_areas(request, title, format, areas, **kwargs):


def query_args(request, format, type=None):
try:
generation = int(request.GET.get('generation', 0))
except ValueError:
raise ViewException(format, _('Bad generation specified'), 400)
if not generation:
generation = Generation.objects.current().id

try:
min_generation = int(request.GET.get('min_generation', 0))
except ValueError:
raise ViewException(format, _('Bad min_generation specified'), 400)
if not min_generation:
min_generation = generation
generation, min_generation = Generation.objects.query_args(request, format)

if type is None:
type = request.GET.get('type', '')
Expand Down
9 changes: 4 additions & 5 deletions mapit/views/postcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,11 @@ def postcode(request, postcode, format=None):
if not is_valid_postcode(postcode):
raise ViewException(format, "Postcode '%s' is not valid." % postcode, 400)
postcode = get_object_or_404(Postcode, format=format, postcode=postcode)
try:
generation = int(request.GET['generation'])
except:
generation = Generation.objects.current()

generation, min_generation = Generation.objects.query_args(request, format)

if not hasattr(countries, 'is_special_postcode') or not countries.is_special_postcode(postcode.postcode):
areas = list(add_codes(Area.objects.by_postcode(postcode, generation)))
areas = list(add_codes(Area.objects.by_postcode(postcode, generation, min_generation)))
else:
areas = []

Expand Down

0 comments on commit 7644fec

Please sign in to comment.