async def get_neighbourhood(postcode_like: PostCodeLike) -> Optional[Neighbourhood]:
try:<EOL><INDENT>postcode = await get_postcode(postcode_like)<EOL><DEDENT>except CachingError as e:<EOL><INDENT>raise e<EOL><DEDENT>else:<EOL><INDENT>if postcode is None:<EOL><INDENT>return None<EOL><DEDENT>elif postcode.neighbourhood is not None:<EOL><INDENT>return postcode.neighbourhood<EOL><DEDENT><DEDENT>try:<EOL><INDENT>data = await fetch_neighbourhood(postcode.lat, postcode.long)<EOL><DEDENT>except ApiError as e:<EOL><INDENT>raise CachingError(f"<STR_LIT>")<EOL><DEDENT>if data is not None:<EOL><INDENT>neighbourhood = Neighbourhood.from_dict(data)<EOL>locations = [Location.from_dict(neighbourhood, postcode, location) for location in data["<STR_LIT>"]]<EOL>links = [Link.from_dict(neighbourhood, link) for link in data["<STR_LIT>"]]<EOL>with Neighbourhood._meta.database.atomic():<EOL><INDENT>neighbourhood.save()<EOL>postcode.neighbourhood = neighbourhood<EOL>postcode.save()<EOL>for location in locations:<EOL><INDENT>location.save()<EOL><DEDENT>for link in links:<EOL><INDENT>link.save()<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>neighbourhood = None<EOL><DEDENT>return neighbourhood<EOL>
Gets a police neighbourhood from the database.
Acts as a middleware between us and the API, caching results.
:param postcode_like: The UK postcode to look up.
:return: The Neighbourhood or None if the postcode does not exist.
:raises CachingError: If the needed neighbourhood is not in cache, and the fetch isn't responding.

todo save locations/links