fix locationredirects breaking querysets
This commit is contained in:
parent
07a3c5ffa9
commit
00ec22c334
4 changed files with 37 additions and 25 deletions
|
@ -48,8 +48,9 @@ class LocationSlugManager(models.Manager):
|
|||
if self.model != LocationSlug:
|
||||
raise TypeError
|
||||
qs = self.get_queryset()
|
||||
qs = qs.select_related('redirect__target', *('redirect__target__'+model._meta.default_related_name
|
||||
for model in get_submodels(Location) + [LocationRedirect]))
|
||||
qs = qs.select_related('locationredirects__target',
|
||||
*('locationredirects__target__'+model._meta.default_related_name
|
||||
for model in get_submodels(Location) + [LocationRedirect]))
|
||||
return qs
|
||||
|
||||
|
||||
|
@ -108,15 +109,6 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
|
|||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def serialize(self, detailed=True, **kwargs):
|
||||
result = super().serialize(detailed=detailed, **kwargs)
|
||||
if not detailed:
|
||||
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
|
||||
|
||||
@property
|
||||
def add_search(self):
|
||||
return ' '.join((
|
||||
|
@ -495,6 +487,7 @@ class DynamicLocation(CustomLocationProxyMixin, SpecificLocation, models.Model):
|
|||
pass
|
||||
|
||||
def serialize_position(self, request=None):
|
||||
# todo: make this pretty
|
||||
custom_location = self.get_custom_location(request=request)
|
||||
if custom_location is None:
|
||||
return {
|
||||
|
@ -505,7 +498,8 @@ class DynamicLocation(CustomLocationProxyMixin, SpecificLocation, models.Model):
|
|||
'title': str(self.title),
|
||||
'subtitle': '%s %s, %s' % (_('currently unavailable'), _('(moving)'), self.subtitle)
|
||||
}
|
||||
result = custom_location.serialize(simple_geometry=True)
|
||||
from c3nav.mapdata.schemas.models import CustomLocationSchema
|
||||
result = CustomLocationSchema.model_validate(custom_location).model_dump()
|
||||
result.update({
|
||||
'available': True,
|
||||
'id': self.pk,
|
||||
|
@ -586,6 +580,7 @@ class Position(CustomLocationProxyMixin, models.Model):
|
|||
return result
|
||||
|
||||
def serialize_position(self, request=None):
|
||||
# todo: make this pretty
|
||||
custom_location = self.get_custom_location(request=request)
|
||||
if custom_location is None:
|
||||
return {
|
||||
|
@ -596,7 +591,8 @@ class Position(CustomLocationProxyMixin, models.Model):
|
|||
'title': self.name,
|
||||
'subtitle': _('currently unavailable'),
|
||||
}
|
||||
result = custom_location.serialize(simple_geometry=True)
|
||||
from c3nav.mapdata.schemas.models import CustomLocationSchema
|
||||
result = CustomLocationSchema.model_validate(custom_location).model_dump()
|
||||
result.update({
|
||||
'available': True,
|
||||
'id': 'p:%s' % self.secret,
|
||||
|
@ -619,20 +615,22 @@ class Position(CustomLocationProxyMixin, models.Model):
|
|||
def slug(self):
|
||||
return 'p:%s' % self.secret
|
||||
|
||||
@property
|
||||
def subtitle(self):
|
||||
return _('Position')
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
return 'my_location'
|
||||
|
||||
@property
|
||||
def effective_icon(self):
|
||||
return self.icon
|
||||
|
||||
@property
|
||||
def effective_slug(self):
|
||||
return self.slug
|
||||
|
||||
def serialize(self, *args, **kwargs):
|
||||
return {
|
||||
'dynamic': True,
|
||||
'id': 'p:%s' % self.secret,
|
||||
'slug': 'p:%s' % self.secret,
|
||||
'icon': 'my_location',
|
||||
'title': self.name,
|
||||
'subtitle': _('Position'),
|
||||
}
|
||||
|
||||
def details_display(self, **kwargs):
|
||||
return {
|
||||
'id': self.pk,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from contextlib import suppress
|
||||
from typing import Annotated, ClassVar, Literal, Optional, Union, Any
|
||||
|
||||
from django.db.models import Model
|
||||
|
@ -545,6 +546,14 @@ class TrackablePositionSchema(BaseSchema):
|
|||
example="Near Bällebad"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_overrides(cls, value) -> dict:
|
||||
from c3nav.mapdata.models.locations import Position
|
||||
value: Position
|
||||
return {
|
||||
"id": value.slug,
|
||||
}
|
||||
|
||||
|
||||
class LocationTypeSchema(BaseSchema):
|
||||
locationtype: str = APIField(title="location type",
|
||||
|
@ -695,6 +704,8 @@ class SlimDynamicLocationLocationSchema(SlimLocationMixin, FullDynamicLocationLo
|
|||
def get_locationtype(v: Any):
|
||||
if isinstance(v, Model):
|
||||
return v._meta.model_name
|
||||
with suppress(AttributeError):
|
||||
return v.locationtype
|
||||
return v["locationtype"]
|
||||
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ def locations_for_request(request) -> Mapping[int, LocationSlug]:
|
|||
conditions = []
|
||||
for model in get_submodels(Location):
|
||||
related_name = model._meta.default_related_name
|
||||
for prefix in ('', 'redirect__target__'):
|
||||
for prefix in ('', 'locationredirects__target__'):
|
||||
condition = Q(**{prefix + related_name + '__isnull': False})
|
||||
# noinspection PyUnresolvedReferences
|
||||
condition &= model.q_for_request(request, prefix=prefix + related_name + '__')
|
||||
|
@ -52,7 +52,7 @@ def locations_for_request(request) -> Mapping[int, LocationSlug]:
|
|||
)
|
||||
|
||||
locations = locations.filter(reduce(operator.or_, conditions))
|
||||
locations = locations.select_related('redirect', 'locationgroups__category')
|
||||
locations = locations.select_related('locationredirects', 'locationgroups__category')
|
||||
|
||||
# prefetch locationgroups
|
||||
base_qs = LocationGroup.qs_for_request(request).select_related('category', 'label_settings')
|
||||
|
@ -275,6 +275,8 @@ def get_custom_location_for_request(slug: str, request):
|
|||
|
||||
@dataclass
|
||||
class CustomLocation:
|
||||
new_serialize: ClassVar = True
|
||||
|
||||
locationtype: ClassVar = "customlocation"
|
||||
|
||||
can_search = True
|
||||
|
|
|
@ -534,6 +534,7 @@ CustomLocationDescription = namedtuple('CustomLocationDescription', ('space', 'a
|
|||
'areas', 'near_area', 'near_poi', 'nearby'))
|
||||
|
||||
|
||||
# todo: make generic
|
||||
class BaseRouterProxy:
|
||||
def __init__(self, src):
|
||||
self.src = src
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue