summaryrefslogtreecommitdiff
path: root/ishtar_common/views_item.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2019-02-05 17:05:34 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2019-04-24 19:38:56 +0200
commitc68a0bb8412f261b535d8cebb4b533cdc7b148e7 (patch)
treef9536b686833b6f406761359895fc641262c8003 /ishtar_common/views_item.py
parent9b6182875de760e3c4e5a6843ee56d25e869c4b8 (diff)
downloadIshtar-c68a0bb8412f261b535d8cebb4b533cdc7b148e7.tar.bz2
Ishtar-c68a0bb8412f261b535d8cebb4b533cdc7b148e7.zip
Map: optimize query tretment too manage large results
Diffstat (limited to 'ishtar_common/views_item.py')
-rw-r--r--ishtar_common/views_item.py78
1 files changed, 39 insertions, 39 deletions
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index 4a6337fe7..4e8a742e2 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -17,7 +17,7 @@ from django.contrib.staticfiles.templatetags.staticfiles import static
from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse, NoReverseMatch
-from django.db.models import Q, ImageField
+from django.db.models import Q, ImageField, Func, ExpressionWrapper, FloatField
from django.db.models.fields import FieldDoesNotExist
from django.http import HttpResponse
from django.shortcuts import render
@@ -991,7 +991,7 @@ def _format_val(val):
return unicode(val)
-def _format_geojson(rows):
+def _format_geojson(rows, link_template):
data = {
'type': 'FeatureCollection',
'crs': {
@@ -1000,38 +1000,31 @@ def _format_geojson(rows):
'name': 'EPSG:4326'
}
},
+ 'link_template': link_template,
'features': [],
'no-geo': []
}
if not rows:
return data
- geo_attr, name_attr = None, None
- full, idx = len(rows), 0
- while not geo_attr and idx < full:
- row = rows[idx]
- for attr in row:
- if attr.endswith('point_2d'):
- geo_attr = attr
- if attr in ['name', 'cached_label']:
- name_attr = attr
- idx += 1
- if not geo_attr or not name_attr:
- return data
for row in rows:
- feat = {'name': row[name_attr], 'id': row['id'], 'link': row['link']}
- if not row.get(geo_attr, None):
+ feat = {'id': row[0], 'name': row[1]}
+ if not row[2]:
data['no-geo'].append(feat)
continue
- feature = {'type': 'Feature'}
- feature['properties'] = feat
- point = GEOSGeometry(row[geo_attr])
- feature['geometry'] = json.loads(point.json)
+ feature = {
+ 'type': 'Feature',
+ 'properties': feat,
+ 'geometry': {
+ u'type': u'Point',
+ u'coordinates': [row[2], row[3]]
+ }
+ }
data['features'].append(feature)
return data
def _get_data_from_query(items, query_table_cols, request, extra_request_keys,
- do_not_deduplicate=False):
+ point_field=None):
for query_keys in query_table_cols:
if not isinstance(query_keys, (tuple, list)):
query_keys = [query_keys]
@@ -1049,17 +1042,17 @@ def _get_data_from_query(items, query_table_cols, request, extra_request_keys,
query_key.replace(".", "__") # class style to query
values = ['id'] + query_table_cols
-
- c_ids, data_list = [], []
- for item in items.values(*values):
- # manual deduplicate when distinct is not enough
- if not do_not_deduplicate and item['id'] in c_ids:
- continue
- c_ids.append(item['id'])
- data = [item['id']]
- for key in query_table_cols:
- data.append(item[key])
- data_list.append(data)
+ if point_field:
+ items = items.annotate(
+ point_x=ExpressionWrapper(
+ Func(point_field, function='ST_X'), output_field=FloatField())
+ )
+ items = items.annotate(
+ point_y=ExpressionWrapper(
+ Func(point_field, function='ST_Y'), output_field=FloatField())
+ )
+ values += ['point_x', 'point_y']
+ data_list = items.values_list(*values)
return data_list
@@ -1632,9 +1625,10 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
items = [item.get_previous(old) for item in items]
if data_type == 'json-map':
+ point_field = query_table_cols.pop()
datas = _get_data_from_query(
items, query_table_cols, request, my_extra_request_keys,
- do_not_deduplicate)
+ point_field=point_field)
else:
datas = _get_data_from_query_old(
items, query_table_cols, request, my_extra_request_keys,
@@ -1661,6 +1655,13 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
link_ext_template = '<a href="{}" target="_blank">{}</a>'
if data_type.startswith("json"):
rows = []
+ if data_type == 'json-map':
+
+ lnk = link_template % reverse('show-' + default_name,
+ args=[999999, ''])
+ lnk = lnk.replace('999999', "<pk>")
+ data = json.dumps(_format_geojson(datas, lnk))
+ return HttpResponse(data, content_type='application/json')
for data in datas:
try:
lnk_template = link_template
@@ -1671,8 +1672,10 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
'**WARN "show-' + default_name + '" args ('
+ unicode(data[0]) + ") url not available")
lnk = ''
- res = {'id': data[0]}
- res['link'] = lnk
+ res = {
+ 'id': data[0],
+ 'link': lnk
+ }
for idx, value in enumerate(data[1:]):
if value:
table_col = table_cols[idx]
@@ -1697,9 +1700,7 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
elif 'name' in res:
res['value'] = res.pop('name')
rows.append(res)
- if data_type == 'json-map':
- data = json.dumps(_format_geojson(rows))
- elif full == 'shortcut':
+ if full == 'shortcut':
data = json.dumps(rows)
else:
data = json.dumps({
@@ -1714,7 +1715,6 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
return HttpResponse(data, content_type='application/json')
elif data_type == "csv":
response = HttpResponse(content_type='text/csv')
- n = datetime.datetime.now()
filename = u'%s_%s.csv' % (default_name,
n.strftime('%Y%m%d-%H%M%S'))
response['Content-Disposition'] = 'attachment; filename=%s' \