base_adresse: add lat/lon/type to address'id to get by id through reverse (#55522)

This commit is contained in:
Benjamin Dauvergne 2021-07-12 13:16:28 +02:00
parent 3a01c57129
commit 18b2e436ff
2 changed files with 50 additions and 14 deletions

View File

@ -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': []}
@ -155,20 +157,35 @@ class BaseAdresse(BaseResource):
data = self.format_address_data(feature)
result.append(data)
address, created = AddressCacheModel.objects.get_or_create(
api_id=data['id'], defaults={'data': data}
api_id=data['id'][:30], defaults={'data': data}
)
if not created:
address.update_timestamp()
return {'data': result}
def get_by_id(self, request, id):
def get_by_id(self, request, id, citycode=None):
try:
address = AddressCacheModel.objects.get(api_id=id)
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[:30])
except AddressCacheModel.DoesNotExist:
return {'err': _('Address ID not found')}
address.update_timestamp()
return {'data': [address.data]}
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]}
self.logger.error('get_by_id: id %s was not found', id)
return {'err': _('Address ID not found')}
@endpoint(
pattern='(?P<q>.+)?$',
@ -225,7 +242,7 @@ class BaseAdresse(BaseResource):
continue # skip unknown
result = self.format_address_data(feature)
address, created = AddressCacheModel.objects.get_or_create(
api_id=result['id'], defaults={'data': result}
api_id=result['id'][:30], defaults={'data': result}
)
if not created:
address.update_timestamp()

View File

@ -797,11 +797,12 @@ 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'
assert data['address']['road'] == 'Rue Roger Halope'
assert data['ban_id'] == '49007_6950_be54bd'
@mock.patch('passerelle.utils.Request.get')
@ -833,7 +834,7 @@ def test_base_adresse_addresses_qs_coordinates(mocked_get, app, base_adresse_coo
assert 'lon=43' in mocked_get.call_args[0][0]
def test_base_adresse_addresses_cache(app, base_adresse, mock_api_adresse_data_gouv_fr_search):
def test_base_adresse_addresses_cache(app, base_adresse, mock_api_adresse_data_gouv_fr_search, caplog):
resp = app.get('/base-adresse/%s/addresses?q=plop' % base_adresse.slug)
assert mock_api_adresse_data_gouv_fr_search.call['count'] == 1
@ -841,7 +842,7 @@ def test_base_adresse_addresses_cache(app, base_adresse, mock_api_adresse_data_g
assert data['text'] == 'Rue Roger Halope 49000 Angers'
api_id = data['id']
assert AddressCacheModel.objects.filter(api_id=api_id).exists()
assert AddressCacheModel.objects.filter(api_id=api_id[:30]).exists()
assert AddressCacheModel.objects.count() == 1
resp = app.get('/base-adresse/%s/addresses?id=%s' % (base_adresse.slug, api_id))
@ -851,6 +852,21 @@ 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
# no cache and id has changed
AddressCacheModel.objects.all().delete()
api_id = '49007_XXXX_be54bd~47.474633~-0.593775~Rue%20Roger%20Halope%2049000%20Angers'
resp = app.get('/base-adresse/%s/addresses?id=%s' % (base_adresse.slug, api_id))
assert resp.json['err'] == 'Address ID not found'
def test_base_adresse_addresses_cache_err(app, base_adresse, mock_api_adresse_data_gouv_fr_search):
@ -882,7 +898,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
@ -924,7 +943,7 @@ def test_base_adresse_reverse_cache(
assert data['text'] == 'Rue Roger Halope 49000 Angers'
api_id = data['id']
assert AddressCacheModel.objects.filter(api_id=api_id).exists()
assert AddressCacheModel.objects.filter(api_id=api_id[:30]).exists()
assert AddressCacheModel.objects.count() == 1
first_timestamp = AddressCacheModel.objects.get().timestamp