improve editor geometry API performance using prefetch_related

This commit is contained in:
Laura Klünder 2017-05-29 16:36:17 +02:00
parent 621cb8f32e
commit c65f01d620
2 changed files with 22 additions and 10 deletions

View file

@ -28,7 +28,7 @@ class EditorViewSet(ViewSet):
holes_geom = cascaded_union([hole.geometry for hole in holes]) holes_geom = cascaded_union([hole.geometry for hole in holes])
buildings = section.buildings.all() buildings = section.buildings.all()
buildings_geom = cascaded_union([building.geometry for building in buildings]) buildings_geom = cascaded_union([building.geometry for building in buildings])
spaces = {space.id: space for space in section.spaces.all()} spaces = {space.id: space for space in section.spaces.all().prefetch_related('groups')}
for space in spaces.values(): for space in spaces.values():
if space.outside: if space.outside:
space.geometry = space.geometry.difference(buildings_geom) space.geometry = space.geometry.difference(buildings_geom)
@ -46,7 +46,8 @@ class EditorViewSet(ViewSet):
def add_spaces(level): def add_spaces(level):
results.extend(space for space in spaces.values() if space.level == level) results.extend(space for space in spaces.values() if space.level == level)
areas = [a for a in Area.objects.filter(space__section=section, space__level=level) if a.get_color()] areas = Area.objects.filter(space__section=section, space__level=level).prefetch_related('groups')
areas = [area for area in areas if area.get_color()]
for area in areas: for area in areas:
area.geometry = area.geometry.intersection(spaces[area.space_id].geometry) area.geometry = area.geometry.intersection(spaces[area.space_id].geometry)
results.extend((area for area in areas if not area.geometry.is_empty)) results.extend((area for area in areas if not area.geometry.is_empty))
@ -61,13 +62,13 @@ class EditorViewSet(ViewSet):
add_spaces('upper') add_spaces('upper')
return Response([obj.to_geojson() for obj in results]) return Response([obj.to_geojson() for obj in results])
elif space is not None: elif space is not None:
space = get_object_or_404(Space, pk=space) space = get_object_or_404(Space.objects.select_related('section'), pk=space)
section = space.section section = space.section
doors = [door for door in section.doors.all() if door.geometry.intersects(space.geometry)] doors = [door for door in section.doors.all() if door.geometry.intersects(space.geometry)]
doors_geom = cascaded_union([door.geometry for door in doors]) doors_geom = cascaded_union([door.geometry for door in doors])
spaces = [s for s in section.spaces.filter(level='normal') spaces = [s for s in section.spaces.filter(level='normal').prefetch_related('groups')
if s.geometry.intersects(doors_geom) and s.pk != space.pk] if s.geometry.intersects(doors_geom) and s.pk != space.pk]
space.bounds = True space.bounds = True
@ -77,11 +78,11 @@ class EditorViewSet(ViewSet):
doors, doors,
spaces, spaces,
[space], [space],
space.areas.all(), space.areas.all().prefetch_related('groups'),
space.stairs.all(), space.stairs.all(),
space.obstacles.all(), space.obstacles.all(),
space.lineobstacles.all(), space.lineobstacles.all(),
space.points.all(), space.points.all().prefetch_related('groups'),
) )
return Response(sum([self._get_geojsons(obj) for obj in results], ())) return Response(sum([self._get_geojsons(obj) for obj in results], ()))
else: else:

View file

@ -112,13 +112,24 @@ class Location(LocationSlug, EditorFormMixin, models.Model):
return self._meta.verbose_name + ' ' + self.slug return self._meta.verbose_name + ' ' + self.slug
return super().title return super().title
@staticmethod
def bla():
pass
def get_color(self): def get_color(self):
if self.color: if self.color:
return self.color return self.color
color_group = self.groups.filter(color__isnull=False).order_by('compiled_area', 'compiled_room').first() # dont filter in the query here so prefetch_related works
if color_group: groups = [group for group in self.groups.all() if group.color is not None]
return color_group.color if not groups:
return None return None
for group in groups:
if group.compiled_area:
return group.color
for group in groups:
if group.compiled_room:
return group.color
return groups[0].color
class SpecificLocation(Location, models.Model): class SpecificLocation(Location, models.Model):