From c761608a1d77215718e11c9e79182b92b3536d97 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 12 Jul 2021 13:16:28 +0200 Subject: [PATCH 2/4] base_adresse: add lat/lon/type to address'id to get by id through reverse (#55522) --- .../migrations/0019_auto_20210712_1233.py | 18 +++++++++++ passerelle/apps/base_adresse/models.py | 30 +++++++++++++++---- tests/test_base_adresse.py | 16 ++++++++-- 3 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 passerelle/apps/base_adresse/migrations/0019_auto_20210712_1233.py diff --git a/passerelle/apps/base_adresse/migrations/0019_auto_20210712_1233.py b/passerelle/apps/base_adresse/migrations/0019_auto_20210712_1233.py new file mode 100644 index 00000000..9b9e1b7e --- /dev/null +++ b/passerelle/apps/base_adresse/migrations/0019_auto_20210712_1233.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.19 on 2021-07-12 10:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('base_adresse', '0018_text_to_jsonb'), + ] + + operations = [ + migrations.AlterField( + model_name='addresscachemodel', + name='api_id', + field=models.CharField(max_length=128, unique=True), + ), + ] diff --git a/passerelle/apps/base_adresse/models.py b/passerelle/apps/base_adresse/models.py index 25977151..9a4e6720 100644 --- a/passerelle/apps/base_adresse/models.py +++ b/passerelle/apps/base_adresse/models.py @@ -87,7 +87,9 @@ class BaseAdresse(BaseResource): value = value[len(house_number) :].strip() result['address']['road'] = value elif prop == 'id': - result['id'] = value + result['ban_id'] = value + result['id'] = '%s~%s~%s' % (value, result['lat'], result['lon']) + result['id'] = '%s~%s' % (result['id'], result['text']) return result @endpoint( @@ -117,7 +119,7 @@ class BaseAdresse(BaseResource): self, request, id=None, q=None, zipcode='', citycode=None, lat=None, lon=None, page_limit=5 ): if id is not None: - return self.get_by_id(request, id=id) + return self.get_by_id(request, id=id, citycode=citycode) if not q: return {'data': []} @@ -162,13 +164,29 @@ class BaseAdresse(BaseResource): return {'data': result} - def get_by_id(self, request, id): + def get_by_id(self, request, id, citycode=None): + try: + ban_id, lat, lon, q = id.split('~', 4) + except ValueError: # retrocompatibility with raw BAN id + ban_id = id + lat, lon, q = None, None, None + # Try cache try: address = AddressCacheModel.objects.get(api_id=id) except AddressCacheModel.DoesNotExist: + pass + else: + address.update_timestamp() + return {'data': [address.data]} + # Use search with label as q and lat/lon as geographic hint + if q and lat and lon: + results = self.addresses(request, q=q, lat=lat, lon=lon, citycode=citycode)['data'] + for result in results: # match by id if possible + if result['ban_id'] == ban_id: + return {'data': [result]} + return results + else: # retrocompatibility with raw BAN id return {'err': _('Address ID not found')} - address.update_timestamp() - return {'data': [address.data]} @endpoint( pattern='(?P.+)?$', @@ -640,7 +658,7 @@ class CityModel(UnaccentNameMixin, models.Model): class AddressCacheModel(models.Model): - api_id = models.CharField(max_length=30, unique=True) + api_id = models.CharField(max_length=128, unique=True) data = JSONField() timestamp = models.DateTimeField(auto_now=True) diff --git a/tests/test_base_adresse.py b/tests/test_base_adresse.py index 18f90f36..2806409d 100644 --- a/tests/test_base_adresse.py +++ b/tests/test_base_adresse.py @@ -797,7 +797,7 @@ def test_base_adresse_addresses(mocked_get, app, base_adresse): assert data['lon'] == '-0.593775' assert data['display_name'] == 'Rue Roger Halope 49000 Angers' assert data['text'] == 'Rue Roger Halope 49000 Angers' - assert data['id'] == '49007_6950_be54bd' + assert data['id'] == '49007_6950_be54bd~47.474633~-0.593775~Rue Roger Halope 49000 Angers' assert data['address']['city'] == 'Angers' assert data['address']['postcode'] == '49000' assert data['address']['citycode'] == '49007' @@ -851,6 +851,15 @@ def test_base_adresse_addresses_cache(app, base_adresse, mock_api_adresse_data_g resp = app.get('/base-adresse/%s/addresses?q=plop' % base_adresse.slug) assert AddressCacheModel.objects.count() == 1 # no new object has been created + assert mock_api_adresse_data_gouv_fr_search.call['count'] == 2 + + # no cache + AddressCacheModel.objects.all().delete() + resp = app.get('/base-adresse/%s/addresses?id=%s' % (base_adresse.slug, api_id)) + assert AddressCacheModel.objects.count() == 1 + assert mock_api_adresse_data_gouv_fr_search.call['count'] == 3 + assert data['text'] == 'Rue Roger Halope 49000 Angers' + assert 'address' in data def test_base_adresse_addresses_cache_err(app, base_adresse, mock_api_adresse_data_gouv_fr_search): @@ -882,7 +891,10 @@ def test_base_adresse_addresses_clean_cache(app, base_adresse, freezer, mock_api assert AddressCacheModel.objects.count() == 1 freezer.move_to(datetime.timedelta(hours=1, seconds=1)) - resp = app.get('/base-adresse/%s/addresses?id=%s' % (base_adresse.slug, '49007_6950_be54bd')) + resp = app.get( + '/base-adresse/%s/addresses?id=%s' + % (base_adresse.slug, '49007_6950_be54bd~47.474633~-0.593775~Rue%20Roger%20Halope%2049000%20Angers') + ) call_command('cron', 'hourly') assert AddressCacheModel.objects.count() == 1 -- 2.32.0.rc0