add first subtitle code
This commit is contained in:
parent
ebca3361d3
commit
25b478f227
2 changed files with 41 additions and 20 deletions
|
@ -186,32 +186,34 @@ class LocationGroupViewSet(MapdataViewSet):
|
||||||
class LocationViewSet(RetrieveModelMixin, GenericViewSet):
|
class LocationViewSet(RetrieveModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
only accesses locations that have can_search or can_describe set to true.
|
only accesses locations that have can_search or can_describe set to true.
|
||||||
add ?detailed=1 to show all attributes, add ?group=<id> to filter by group.
|
add ?detailed=1 to show all attributes, add ?geometry=1 to show geometries, add ?group=<id> to filter by group
|
||||||
/{id}/ add ?show_redirect=1 to suppress redirects and show them as JSON.
|
/{id}/ add ?show_redirect=1 to suppress redirects and show them as JSON.
|
||||||
/search/ only accesses locations that have can_search set to true. Add GET Parameter “s” to search.
|
/search/ only accesses locations that have can_search set to true. Add GET Parameter “s” to search.
|
||||||
"""
|
"""
|
||||||
queryset = LocationSlug.objects.all()
|
queryset = LocationSlug.objects.all()
|
||||||
lookup_field = 'slug'
|
lookup_field = 'slug'
|
||||||
|
|
||||||
def get_queryset(self, detailed=False, subconditions=None, group=None):
|
def get_queryset(self, search=False, group=None):
|
||||||
queryset = super().get_queryset().order_by('id')
|
queryset = super().get_queryset().order_by('id')
|
||||||
|
|
||||||
conditions = []
|
conditions = []
|
||||||
for model in get_submodels(Location):
|
for model in get_submodels(Location):
|
||||||
if group is not None and not hasattr(model, 'groups'):
|
if group is not None and not hasattr(model, 'groups'):
|
||||||
continue
|
continue
|
||||||
condition = Q(**{model._meta.default_related_name + '__isnull': False})
|
related_name = model._meta.default_related_name
|
||||||
if subconditions:
|
condition = Q(**{related_name+'__isnull': False})
|
||||||
condition &= reduce(operator.or_, (Q(**{model._meta.default_related_name+'__'+name: value})
|
if search:
|
||||||
for name, value in subconditions.items()))
|
condition &= Q(**{related_name+'__can_search': True})
|
||||||
|
else:
|
||||||
|
condition &= Q(**{related_name+'__can_search': True, related_name+'__can_describe': True})
|
||||||
if group is not None:
|
if group is not None:
|
||||||
condition &= Q(**{model._meta.default_related_name+'__groups': group})
|
condition &= Q(**{related_name+'__groups': group})
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
condition &= model.q_for_request(self.request, prefix=model._meta.default_related_name+'__')
|
condition &= model.q_for_request(self.request, prefix=related_name+'__')
|
||||||
conditions.append(condition)
|
conditions.append(condition)
|
||||||
queryset = queryset.filter(reduce(operator.or_, conditions))
|
queryset = queryset.filter(reduce(operator.or_, conditions))
|
||||||
|
|
||||||
if detailed:
|
# prefetch locationgroups
|
||||||
base_qs = LocationGroup.objects.all().select_related('category')
|
base_qs = LocationGroup.objects.all().select_related('category')
|
||||||
for model in get_submodels(SpecificLocation):
|
for model in get_submodels(SpecificLocation):
|
||||||
queryset = queryset.prefetch_related(Prefetch(model._meta.default_related_name + '__groups',
|
queryset = queryset.prefetch_related(Prefetch(model._meta.default_related_name + '__groups',
|
||||||
|
@ -221,8 +223,7 @@ class LocationViewSet(RetrieveModelMixin, GenericViewSet):
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
detailed = 'detailed' in request.GET
|
detailed = 'detailed' in request.GET
|
||||||
|
geometry = 'geometry' in request.GET
|
||||||
subconditions = {'can_search': True, 'can_describe': True}
|
|
||||||
|
|
||||||
group = None
|
group = None
|
||||||
if 'group' in request.GET:
|
if 'group' in request.GET:
|
||||||
|
@ -233,9 +234,10 @@ class LocationViewSet(RetrieveModelMixin, GenericViewSet):
|
||||||
except LocationGroupCategory.DoesNotExist:
|
except LocationGroupCategory.DoesNotExist:
|
||||||
raise NotFound(detail=_('group not found.'))
|
raise NotFound(detail=_('group not found.'))
|
||||||
|
|
||||||
queryset = self.get_queryset(detailed=detailed, subconditions=subconditions, group=group)
|
queryset = self.get_queryset(group=group)
|
||||||
|
|
||||||
return Response([obj.get_child().serialize(include_type=True, detailed=detailed) for obj in queryset])
|
return Response([obj.get_child().serialize(include_type=True, detailed=detailed, geometry=geometry)
|
||||||
|
for obj in queryset])
|
||||||
|
|
||||||
def retrieve(self, request, slug=None, *args, **kwargs):
|
def retrieve(self, request, slug=None, *args, **kwargs):
|
||||||
result = Location.get_by_slug(slug, self.get_queryset())
|
result = Location.get_by_slug(slug, self.get_queryset())
|
||||||
|
@ -259,19 +261,22 @@ class LocationViewSet(RetrieveModelMixin, GenericViewSet):
|
||||||
@list_route(methods=['get'])
|
@list_route(methods=['get'])
|
||||||
def search(self, request):
|
def search(self, request):
|
||||||
detailed = 'detailed' in request.GET
|
detailed = 'detailed' in request.GET
|
||||||
|
geometry = 'geometry' in request.GET
|
||||||
search = request.GET.get('s')
|
search = request.GET.get('s')
|
||||||
|
|
||||||
queryset = self.get_queryset(detailed=detailed, subconditions={'can_search': True})
|
queryset = self.get_queryset(search=True)
|
||||||
|
|
||||||
if not search:
|
if not search:
|
||||||
return Response([obj.get_child().serialize(include_type=True, detailed=detailed) for obj in queryset])
|
return Response([obj.get_child().serialize(include_type=True, detailed=detailed, geometry=geometry)
|
||||||
|
for obj in queryset])
|
||||||
|
|
||||||
words = search.lower().split(' ')[:10]
|
words = search.lower().split(' ')[:10]
|
||||||
results = queryset
|
results = queryset
|
||||||
for word in words:
|
for word in words:
|
||||||
results = [r for r in results if (word in r.title.lower() or (r.slug and word in r.slug.lower()))]
|
results = [r for r in results if (word in r.title.lower() or (r.slug and word in r.slug.lower()))]
|
||||||
# todo: rank results
|
# todo: rank results
|
||||||
return Response([obj.get_child().serialize(include_type=True, detailed=detailed) for obj in results])
|
return Response([obj.get_child().serialize(include_type=True, detailed=detailed, geometry=geometry)
|
||||||
|
for obj in results])
|
||||||
|
|
||||||
|
|
||||||
class SourceViewSet(MapdataViewSet):
|
class SourceViewSet(MapdataViewSet):
|
||||||
|
|
|
@ -81,6 +81,7 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
|
||||||
|
|
||||||
def _serialize(self, **kwargs):
|
def _serialize(self, **kwargs):
|
||||||
result = super()._serialize(**kwargs)
|
result = super()._serialize(**kwargs)
|
||||||
|
result['subtitle'] = self.subtitle
|
||||||
result['can_search'] = self.can_search
|
result['can_search'] = self.can_search
|
||||||
result['can_describe'] = self.can_search
|
result['can_describe'] = self.can_search
|
||||||
return result
|
return result
|
||||||
|
@ -122,6 +123,10 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
|
||||||
return self._meta.verbose_name + ' ' + self.slug
|
return self._meta.verbose_name + ' ' + self.slug
|
||||||
return super().title
|
return super().title
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subtitle(self):
|
||||||
|
return ''
|
||||||
|
|
||||||
def get_color(self, instance=None):
|
def get_color(self, instance=None):
|
||||||
# dont filter in the query here so prefetch_related works
|
# dont filter in the query here so prefetch_related works
|
||||||
if instance is None:
|
if instance is None:
|
||||||
|
@ -150,6 +155,17 @@ class SpecificLocation(Location, models.Model):
|
||||||
result['groups'] = groups
|
result['groups'] = groups
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subtitle(self):
|
||||||
|
related_name = self.__class__._meta.default_related_name
|
||||||
|
groups = tuple(self.groups.all())
|
||||||
|
if groups:
|
||||||
|
group = max((group for group in groups if getattr(group.category, 'allow_'+related_name)),
|
||||||
|
key=lambda group: (group.category.priority, group.priority), default=None)
|
||||||
|
return group.title
|
||||||
|
else:
|
||||||
|
return str(self.__class__._meta.verbose_name)
|
||||||
|
|
||||||
|
|
||||||
class LocationGroupCategory(TitledMixin, models.Model):
|
class LocationGroupCategory(TitledMixin, models.Model):
|
||||||
name = models.SlugField(_('Name'), unique=True, max_length=50)
|
name = models.SlugField(_('Name'), unique=True, max_length=50)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue