add locationredirect api endpoint with new_serialize

This commit is contained in:
Laura Klünder 2024-12-04 12:08:19 +01:00
parent 9debd7c845
commit 40f19afc28
3 changed files with 36 additions and 14 deletions

View file

@ -15,7 +15,7 @@ from c3nav.mapdata.models import (Area, Building, Door, Hole, Level, LocationGro
from c3nav.mapdata.models.access import AccessRestriction, AccessRestrictionGroup
from c3nav.mapdata.models.geometry.space import (POI, Column, CrossDescription, LeaveDescription, LineObstacle,
Obstacle, Ramp)
from c3nav.mapdata.models.locations import DynamicLocation, LabelSettings
from c3nav.mapdata.models.locations import DynamicLocation, LabelSettings, LocationRedirect
from c3nav.mapdata.schemas.filters import (ByCategoryFilter, ByGroupFilter, ByOnTopOfFilter, FilterSchema,
LevelGeometryFilter, SpaceGeometryFilter, BySpaceFilter, ByOverlayFilter)
from c3nav.mapdata.schemas.model_base import schema_description, LabelSettingsSchema
@ -24,7 +24,7 @@ from c3nav.mapdata.schemas.models import (AccessRestrictionGroupSchema, AccessRe
DynamicLocationSchema, HoleSchema, LeaveDescriptionSchema, LevelSchema,
LineObstacleSchema, LocationGroupCategorySchema, LocationGroupSchema,
ObstacleSchema, POISchema, RampSchema, SourceSchema, SpaceSchema, StairSchema,
DataOverlaySchema, DataOverlayFeatureSchema)
DataOverlaySchema, DataOverlayFeatureSchema, LocationRedirectSchema)
mapdata_api_router = APIRouter(tags=["mapdata"])
@ -191,6 +191,10 @@ mapdata_endpoints: dict[str, list[MapdataEndpoint]] = {
model=LocationGroupCategory,
schema=LocationGroupCategorySchema,
),
MapdataEndpoint(
model=LocationRedirect,
schema=LocationRedirectSchema,
),
MapdataEndpoint(
model=Source,
schema=SourceSchema,

View file

@ -445,22 +445,19 @@ class LocationGroup(Location, models.Model):
class LocationRedirect(LocationSlug):
new_serialize = True
target = models.ForeignKey(LocationSlug, related_name='redirects', on_delete=models.CASCADE,
verbose_name=_('target'))
def _serialize(self, include_type=True, **kwargs):
result = super()._serialize(include_type=include_type, **kwargs)
if type(self.target) == LocationSlug:
result['target'] = self.target.get_child().slug
else:
result['target'] = self.target.slug
if include_type:
result['type'] = 'redirect'
result.pop('id')
return result
@property
def target_slug(self):
if type(self.target) is LocationSlug:
return self.target.get_child().effective_slug
return self.target.effective_slug
class Meta:
default_related_name = 'redirect'
default_related_name = 'locationredirects'
class LabelSettings(SerializableMixin, models.Model):

View file

@ -16,7 +16,7 @@ from c3nav.mapdata.schemas.model_base import (AnyLocationID, AnyPositionID, Cust
WithAccessRestrictionSchema, WithLevelSchema,
WithLineStringGeometrySchema, WithPointGeometrySchema,
WithPolygonGeometrySchema, WithSpaceSchema, schema_definitions,
schema_description)
schema_description, LocationSlugSchema)
from c3nav.mapdata.utils.geometry import smart_mapping
from c3nav.mapdata.utils.json import format_geojson
@ -273,6 +273,27 @@ class LocationGroupSchema(LocationSchema, DjangoModelSchema):
)
class LocationRedirectSchema(LocationSlugSchema, DjangoModelSchema):
"""
A location group redirect describes a slug that, when used redirects to another location
"""
slug: NonEmptyStr = APIField( # todo: copy from somewhere?
title="location slug",
description="a slug is a unique way to refer to a location. while locations have a shared ID space, slugs"
"are meants to be human-readable and easy to remember.",
example="entrance",
)
target: PositiveInt = APIField(
title="target",
description="location to redirect to",
)
target_slug: NonEmptyStr = APIField(
title="effective target location slug",
description="effective slug of the target location",
example="lobby",
)
class LocationGroupCategorySchema(TitledSchema, DjangoModelSchema):
"""
A location group category can hold either one or multiple location groups.