Fixes: 1) None; Extra: 1) Removed the entire "geo" module, including migrations, model definitions, admin configurations, utilities, documentation, templates, translations, and related files. Moved functionality to "core".
61 lines
2.1 KiB
Python
61 lines
2.1 KiB
Python
import requests
|
|
from constance import config
|
|
from django.contrib.gis.geos import Point
|
|
from django.db import models
|
|
|
|
|
|
class AddressManager(models.Manager):
|
|
def create(self, raw_data: str, **kwargs):
|
|
"""
|
|
Create an Address instance by geocoding the provided raw address string.
|
|
|
|
Args:
|
|
raw_data (str): The raw address input from the user (e.g., '36 Mornington Rd Loughton England').
|
|
**kwargs: Additional fields to pass to the Address model (e.g., user).
|
|
"""
|
|
if not raw_data:
|
|
raise ValueError("'raw_data' (address string) must be provided.")
|
|
|
|
# Query Nominatim
|
|
params = {
|
|
'format': 'json',
|
|
'addressdetails': 1,
|
|
'q': raw_data,
|
|
}
|
|
resp = requests.get(config.NOMINATIM_URL, params=params)
|
|
resp.raise_for_status()
|
|
results = resp.json()
|
|
if not results:
|
|
raise ValueError(f"No geocoding result for address: {raw_data}")
|
|
data = results[0]
|
|
|
|
# Parse address components
|
|
addr = data.get('address', {})
|
|
street = addr.get('road') or addr.get('pedestrian') or ''
|
|
district = addr.get('city_district') or addr.get('suburb') or ''
|
|
city = addr.get('city') or addr.get('town') or addr.get('village') or ''
|
|
region = addr.get('state') or addr.get('region') or ''
|
|
postal_code = addr.get('postcode') or ''
|
|
country = addr.get('country') or ''
|
|
|
|
# Parse location
|
|
try:
|
|
lat = float(data.get('lat'))
|
|
lon = float(data.get('lon'))
|
|
location = Point(lon, lat, srid=4326)
|
|
except (TypeError, ValueError):
|
|
location = None
|
|
|
|
# Create the model instance, storing both the input string and full API response
|
|
return super().create(
|
|
raw_data=raw_data,
|
|
street=street,
|
|
district=district,
|
|
city=city,
|
|
region=region,
|
|
postal_code=postal_code,
|
|
country=country,
|
|
location=location,
|
|
api_response=data,
|
|
**kwargs
|
|
)
|