new serializer for locationgroup
This commit is contained in:
parent
db938414fb
commit
cc2020e7c3
10 changed files with 58 additions and 57 deletions
|
@ -64,7 +64,7 @@ class LevelGeometryMixin(GeometryMixin):
|
|||
_('Level'),
|
||||
{
|
||||
'id': self.level_id,
|
||||
'slug': self.level.get_slug(),
|
||||
'slug': self.level.effective_slug,
|
||||
'title': self.level.title,
|
||||
'can_search': self.level.can_search,
|
||||
},
|
||||
|
|
|
@ -93,7 +93,7 @@ class SpaceGeometryMixin(GeometryMixin):
|
|||
_('Space'),
|
||||
{
|
||||
'id': self.space_id,
|
||||
'slug': self.space.get_slug(),
|
||||
'slug': self.space.effective_slug,
|
||||
'title': self.space.title,
|
||||
'can_search': self.space.can_search,
|
||||
},
|
||||
|
|
|
@ -81,18 +81,20 @@ class LocationSlug(SerializableMixin, models.Model):
|
|||
return getattr(self, model._meta.default_related_name)
|
||||
return None
|
||||
|
||||
def get_slug(self):
|
||||
@property
|
||||
def effective_slug(self):
|
||||
return self.slug
|
||||
|
||||
def _serialize(self, **kwargs):
|
||||
result = super()._serialize(**kwargs)
|
||||
result["locationtype"] = self.__class__.__name__.lower()
|
||||
result['slug'] = self.get_slug()
|
||||
result['slug'] = self.slug
|
||||
result['effective_slug'] = self.effective_slug
|
||||
return result
|
||||
|
||||
def details_display(self, **kwargs):
|
||||
result = super().details_display(**kwargs)
|
||||
result['display'].insert(2, (_('Slug'), self.get_slug()))
|
||||
result['display'].insert(2, (_('Slug'), self.effective_slug))
|
||||
return result
|
||||
|
||||
@cached_property
|
||||
|
@ -116,9 +118,9 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
|
|||
def serialize(self, detailed=True, **kwargs):
|
||||
result = super().serialize(detailed=detailed, **kwargs)
|
||||
if not detailed:
|
||||
fields = ('id', 'type', 'slug', 'title', 'subtitle', 'icon', 'point', 'bounds', 'grid_square',
|
||||
'locations', 'on_top_of', 'effective_label_settings', 'label_override', 'add_search', 'dynamic',
|
||||
'locationtype', 'geometry')
|
||||
fields = ('id', 'type', 'slug', 'effective_slug', 'title', 'subtitle', 'icon', 'point', 'bounds',
|
||||
'grid_square', 'locations', 'on_top_of', 'effective_label_settings', 'label_override',
|
||||
'add_search', 'dynamic', 'locationtype', 'geometry')
|
||||
result = {name: result[name] for name in fields if name in result}
|
||||
return result
|
||||
|
||||
|
@ -144,7 +146,8 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
|
|||
])
|
||||
return result
|
||||
|
||||
def get_slug(self):
|
||||
@property
|
||||
def effective_slug(self):
|
||||
if self.slug is None:
|
||||
code = self.LOCATION_TYPE_CODES.get(self.__class__.__name__)
|
||||
if code is not None:
|
||||
|
@ -244,7 +247,7 @@ class SpecificLocation(Location, models.Model):
|
|||
category.title if category.single else category.title_plural,
|
||||
tuple({
|
||||
'id': group.pk,
|
||||
'slug': group.get_slug(),
|
||||
'slug': group.effective_slug,
|
||||
'title': group.title,
|
||||
'can_search': group.can_search,
|
||||
} for group in sorted(groups, key=attrgetter('priority'), reverse=True))
|
||||
|
@ -356,6 +359,8 @@ class LocationGroupManager(models.Manager):
|
|||
|
||||
|
||||
class LocationGroup(Location, models.Model):
|
||||
new_serialize = True
|
||||
|
||||
class CanReportMissing(models.TextChoices):
|
||||
DONT_OFFER = "dont_offer", _("don't offer")
|
||||
REJECT = "reject", _("offer in first step, then reject")
|
||||
|
@ -692,7 +697,8 @@ class Position(CustomLocationProxyMixin, models.Model):
|
|||
def slug(self):
|
||||
return 'p:%s' % self.secret
|
||||
|
||||
def get_slug(self):
|
||||
@property
|
||||
def effective_slug(self):
|
||||
return self.slug
|
||||
|
||||
def serialize(self, *args, **kwargs):
|
||||
|
|
|
@ -41,11 +41,15 @@ class DjangoModelSchema(BaseSchema):
|
|||
|
||||
|
||||
class LocationSlugSchema(BaseSchema):
|
||||
slug: NonEmptyStr = APIField(
|
||||
slug: Optional[NonEmptyStr] = APIField(
|
||||
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.\n\n"
|
||||
"if a location doesn't have a slug defined, this field holds a slug generated from the "
|
||||
"are meants to be human-readable and easy to remember.",
|
||||
example="entrance",
|
||||
)
|
||||
effective_slug: NonEmptyStr = APIField(
|
||||
title="effective location slug",
|
||||
description="if a location doesn't have a slug defined, this field holds a slug generated from the "
|
||||
"location type and ID, which will work even if a human-readable slug is defined later.\n\n"
|
||||
"even dynamic locations like coordinates have an (auto-generated) slug.",
|
||||
example="entrance",
|
||||
|
|
|
@ -222,16 +222,7 @@ class LocationGroupSchema(LocationSchema, DjangoModelSchema):
|
|||
)
|
||||
priority: int = APIField() # todo: ???
|
||||
hierarchy: int = APIField() # todo: ???
|
||||
label_settings: Union[
|
||||
Annotated[LabelSettingsSchema, APIField(
|
||||
title="label settings",
|
||||
description="label settings to use for gruop members that don't have their own set",
|
||||
)],
|
||||
Annotated[None, APIField(
|
||||
title="null",
|
||||
description="no label settings set"
|
||||
)],
|
||||
] = APIField(
|
||||
label_settings: Optional[PositiveInt] = APIField(
|
||||
default=None,
|
||||
title="label settings",
|
||||
description=(
|
||||
|
|
18
src/c3nav/mapdata/utils/cache/stats.py
vendored
18
src/c3nav/mapdata/utils/cache/stats.py
vendored
|
@ -90,7 +90,7 @@ def convert_locate(data):
|
|||
for measurement in BeaconMeasurement.objects.all().select_related('space', 'space__level'):
|
||||
pos = CustomLocation(measurement.space.level, measurement.geometry.x, measurement.geometry.y,
|
||||
permissions=set())
|
||||
space_slug = measurement.space.get_slug()
|
||||
space_slug = measurement.space.effective_slug
|
||||
level_label = measurement.space.level.short_label
|
||||
grid_square = pos.grid_square if grid.enabled else None
|
||||
measurement_lookup[pos.pk] = (measurement.pk, grid_square, space_slug, level_label)
|
||||
|
@ -143,23 +143,23 @@ def convert_location(data):
|
|||
location = location.get_child()
|
||||
if isinstance(location, LocationRedirect):
|
||||
continue
|
||||
result['locations']['by_type'].setdefault(location.__class__.__name__.lower(), {})[location.get_slug()] = 0
|
||||
location_slugs[location.pk] = location.get_slug()
|
||||
result['locations']['by_type'].setdefault(location.__class__.__name__.lower(), {})[location.effective_slug] = 0
|
||||
location_slugs[location.pk] = location.effective_slug
|
||||
if isinstance(location, Level):
|
||||
result['locations']['by_level'][location.short_label] = 0
|
||||
result['coordinates']['by_level'][location.short_label] = 0
|
||||
level_labels[location.pk] = location.short_label
|
||||
if isinstance(location, Space):
|
||||
result['locations']['by_space'][location.get_slug()] = 0
|
||||
result['coordinates']['by_space'][location.get_slug()] = 0
|
||||
result['locations']['by_space'][location.effective_slug] = 0
|
||||
result['coordinates']['by_space'][location.effective_slug] = 0
|
||||
if isinstance(location, Area):
|
||||
if getattr(location, 'can_search', False) or getattr(location, 'can_describe', False):
|
||||
result['coordinates']['by_area'][location.get_slug()] = 0
|
||||
result['coordinates']['by_area'][location.effective_slug] = 0
|
||||
if isinstance(location, POI):
|
||||
if getattr(location, 'can_search', False) or getattr(location, 'can_describe', False):
|
||||
result['coordinates']['by_poi'][location.get_slug()] = 0
|
||||
result['coordinates']['by_poi'][location.effective_slug] = 0
|
||||
if isinstance(location, LocationGroup):
|
||||
result['locations']['by_group'][location.get_slug()] = 0
|
||||
result['locations']['by_group'][location.effective_slug] = 0
|
||||
|
||||
for name, value in data:
|
||||
if name[0] != 'pk' or name[0] == 'c:anywhere':
|
||||
|
@ -187,7 +187,7 @@ def convert_location(data):
|
|||
result['locations']['total'] += value
|
||||
location = getattr(location, 'target', location)
|
||||
result['locations']['by_type'].setdefault(location.__class__.__name__.lower(),
|
||||
{})[location.get_slug()] += value
|
||||
{})[location.effective_slug] += value
|
||||
if hasattr(location, 'space_id'):
|
||||
result['locations']['by_space'][location_slugs[location.space_id]] += value
|
||||
if hasattr(location, 'level_id'):
|
||||
|
|
|
@ -342,32 +342,32 @@ class CustomLocation:
|
|||
(_('Slug'), self.pk),
|
||||
(_('Level'), {
|
||||
'id': self.level.pk,
|
||||
'slug': self.level.get_slug(),
|
||||
'slug': self.level.effective_slug,
|
||||
'title': self.level.title,
|
||||
'can_search': self.level.can_search,
|
||||
}),
|
||||
(_('Space'), {
|
||||
'id': self.space.pk,
|
||||
'slug': self.space.get_slug(),
|
||||
'slug': self.space.effective_slug,
|
||||
'title': self.space.title,
|
||||
'can_search': self.space.can_search,
|
||||
} if self.space else None),
|
||||
(_('Areas'), tuple({
|
||||
'id': area.pk,
|
||||
'slug': area.get_slug(),
|
||||
'slug': area.effective_slug,
|
||||
'title': area.title,
|
||||
'can_search': area.can_search,
|
||||
} for area in self.areas)),
|
||||
(_('Grid Square'), self.grid_square or None),
|
||||
(_('Near Area'), {
|
||||
'id': self.near_area.pk,
|
||||
'slug': self.near_area.get_slug(),
|
||||
'slug': self.near_area.effective_slug,
|
||||
'title': self.near_area.title,
|
||||
'can_search': self.near_area.can_search,
|
||||
} if self.near_area else None),
|
||||
(_('Near POI'), {
|
||||
'id': self.near_poi.pk,
|
||||
'slug': self.near_poi.get_slug(),
|
||||
'slug': self.near_poi.effective_slug,
|
||||
'title': self.near_poi.title,
|
||||
'can_search': self.near_poi.can_search,
|
||||
} if self.near_poi else None),
|
||||
|
@ -459,7 +459,8 @@ class CustomLocation:
|
|||
def get_icon(self):
|
||||
return self.icon
|
||||
|
||||
def get_slug(self):
|
||||
@property
|
||||
def effective_slug(self):
|
||||
return self.pk
|
||||
|
||||
@cached_property
|
||||
|
|
|
@ -150,7 +150,7 @@ def preview_location(request, slug):
|
|||
if location is None:
|
||||
raise Http404
|
||||
|
||||
slug = location.get_slug()
|
||||
slug = location.effective_slug
|
||||
|
||||
if isinstance(location, CustomLocation):
|
||||
geometries = [Point(location.x, location.y)]
|
||||
|
|
|
@ -169,7 +169,7 @@ c3nav = {
|
|||
location.elem = c3nav._build_location_html(location);
|
||||
location.title_words = location.title.toLowerCase().split(/\s+/);
|
||||
location.subtitle_words = location.subtitle.toLowerCase().split(/\s+/);
|
||||
location.match = ' ' + location.title_words.join(' ') + ' ' + location.subtitle_words.join(' ') + ' ' + location.slug + ' ' + location.add_search.toLowerCase();
|
||||
location.match = ' ' + location.title_words.join(' ') + ' ' + location.subtitle_words.join(' ') + ' ' + location.effective_slug + ' ' + location.add_search.toLowerCase();
|
||||
locations.push(location);
|
||||
locations_by_id[location.id] = location;
|
||||
if (location.point && location.label_settings) {
|
||||
|
@ -464,7 +464,7 @@ c3nav = {
|
|||
for (var j = 0; j < sublocations.length; j++) {
|
||||
loc = sublocations[j];
|
||||
if (loc.can_search) {
|
||||
loclist.append($('<a>').attr('href', '/l/' + loc.slug + '/details/').attr('data-id', loc.id).click(function (e) {
|
||||
loclist.append($('<a>').attr('href', '/l/' + loc.effective_slug + '/details/').attr('data-id', loc.id).click(function (e) {
|
||||
e.preventDefault();
|
||||
c3nav._locationinput_set($('#destination-input'), c3nav.locations_by_id[parseInt($(this).attr('data-id'))]);
|
||||
c3nav.update_state(false, false, true);
|
||||
|
@ -736,12 +736,12 @@ c3nav = {
|
|||
var url = embed ? '/embed' : '';
|
||||
if (state.routing) {
|
||||
if (state.origin) {
|
||||
url += (state.destination) ? '/r/' + state.origin.slug + '/' + state.destination.slug + '/' : '/o/' + state.origin.slug + '/';
|
||||
url += (state.destination) ? '/r/' + state.origin.effective_slug + '/' + state.destination.effective_slug + '/' : '/o/' + state.origin.effective_slug + '/';
|
||||
} else {
|
||||
url += (state.destination) ? '/d/' + state.destination.slug + '/' : '/r/';
|
||||
url += (state.destination) ? '/d/' + state.destination.effective_slug + '/' : '/r/';
|
||||
}
|
||||
} else {
|
||||
url += state.destination ? ('/l/' + state.destination.slug + '/') : '/';
|
||||
url += state.destination ? ('/l/' + state.destination.effective_slug + '/') : '/';
|
||||
}
|
||||
if (state.details && (url.startsWith('/l/') || url.startsWith('/r/'))) {
|
||||
url += 'details/'
|
||||
|
@ -900,9 +900,8 @@ c3nav = {
|
|||
_buttons_share_click: function (location) {
|
||||
var url = c3nav._get_share_url(false, location);
|
||||
if (navigator.share) {
|
||||
var title
|
||||
, subtitle;
|
||||
if (location.slug) {
|
||||
var title, subtitle;
|
||||
if (location.effective_slug) {
|
||||
title = location.title;
|
||||
subtitle = location.subtitle;
|
||||
} else {
|
||||
|
@ -923,8 +922,8 @@ c3nav = {
|
|||
},
|
||||
_get_share_url: function (with_position, location) {
|
||||
var url, state = $.extend({}, c3nav.state);
|
||||
if (location.slug) {
|
||||
url = '/l/' + location.slug + '/';
|
||||
if (location.effective_slug) {
|
||||
url = '/l/' + location.effective_slug + '/';
|
||||
} else {
|
||||
if (!with_position) {
|
||||
state.center = null;
|
||||
|
|
|
@ -150,24 +150,24 @@ def map_index(request, mode=None, slug=None, slug2=None, details=None, options=N
|
|||
metadata = {
|
||||
'title': _('Route from %s to %s') % (origin.title, destination.title),
|
||||
'preview_img_url': request.build_absolute_uri(reverse('mapdata.preview.route', kwargs={
|
||||
'slug': origin.get_slug(),
|
||||
'slug2': destination.get_slug(),
|
||||
'slug': origin.effective_slug,
|
||||
'slug2': destination.effective_slug,
|
||||
})),
|
||||
'canonical_url': request.build_absolute_uri(reverse('site.index', kwargs={
|
||||
'mode': 'r',
|
||||
'slug': origin.get_slug(),
|
||||
'slug2': destination.get_slug(),
|
||||
'slug': origin.effective_slug,
|
||||
'slug2': destination.effective_slug,
|
||||
'details': False,
|
||||
'options': False,
|
||||
})),
|
||||
}
|
||||
elif destination is not None or origin is not None:
|
||||
if destination is not None:
|
||||
loc_slug = destination.get_slug()
|
||||
loc_slug = destination.effective_slug
|
||||
title = destination.title
|
||||
subtitle = destination.subtitle if hasattr(destination, 'subtitle') else None
|
||||
else:
|
||||
loc_slug = origin.get_slug()
|
||||
loc_slug = origin.effective_slug
|
||||
title = origin.title
|
||||
subtitle = origin.subtitle if hasattr(origin, 'subtitle') else None
|
||||
metadata = {
|
||||
|
@ -579,7 +579,7 @@ def report_missing_choose(request, coordinates):
|
|||
'locations': [
|
||||
{
|
||||
"url": reverse('site.report_create',
|
||||
kwargs={"coordinates": coordinates, "group": group.get_slug()}),
|
||||
kwargs={"coordinates": coordinates, "group": group.effective_slug}),
|
||||
"location": group,
|
||||
"replace_subtitle": group.description
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue