From dcccbb3f66c34c39f0a2538f1bf26bc125adc09b Mon Sep 17 00:00:00 2001 From: Schuyler Erle Date: Wed, 31 Aug 2011 21:51:56 -0700 Subject: [PATCH] Fixup Sanjay's todos. --- gazetteer/places/models.py | 29 +++++++++-------------------- gazetteer/places/views.py | 25 ++++++++++++++++--------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/gazetteer/places/models.py b/gazetteer/places/models.py index 53d31c1..71da611 100644 --- a/gazetteer/places/models.py +++ b/gazetteer/places/models.py @@ -107,34 +107,23 @@ class Feature(models.Model): time_end.short_description = "End Date" def similar_features(self, max_distance=15000, scale_factor=2000, limit=20): - cursor = connection.cursor() - name = unicode(self).replace("'", "''") # escape ' - cursor.execute(""" + sql = """ SELECT *, %f * similarity / (distance + 1.0) AS score FROM ( - SELECT id, url, preferred_name, feature_type_id, - admin1, admin2, is_primary, + SELECT f.*, r.*, similarity(preferred_name, '%s') AS similarity, st_distance_sphere(geometry, 'SRID=4326;%s') AS distance - FROM places_feature + FROM places_feature f LEFT JOIN places_relationship r + ON (f.id=r.feature_from OR f.id=r.feature_to) WHERE geometry && st_buffer('%s', %f) AND preferred_name %%%% '%s' - AND id <> %d + AND f.id <> %d LIMIT %d ) AS whatever ORDER BY similarity / (distance + 1.0) DESC""" - % (scale_factor, name, self.geometry.wkt, self.geometry.wkt, - max_distance*0.00001, name, self.id, limit) - ) - result_list = [] - fields = ('id', 'url', 'preferred_name', 'feature_type_id', 'admin1', 'admin2', 'is_primary') - for row in cursor.fetchall(): - vals = dict(zip(fields, row[:len(fields)])) - p = type(self)(**vals) - p.similarity = row[-3] - p.distance = row[-2] - p.score = row[-1] - result_list.append(p) - return result_list + qset = self.objects.raw(sql, (scale_factor, name, self.geometry.wkt, + self.geometry.wkt, max_distance*0.00001, name, + self.id, limit)) + return qset LANGUAGE_CHOICES = ( ('en', 'English'), diff --git a/gazetteer/places/views.py b/gazetteer/places/views.py index 05dc0fe..0329441 100644 --- a/gazetteer/places/views.py +++ b/gazetteer/places/views.py @@ -88,23 +88,24 @@ def search_related_json(request, id): similar_features = feature.similar_features() d = [] - for s in similar_features: - f = Feature.objects.get(pk=s.id) # This seems inefficient - better to get something like time_frame_id in models method? - if f.time_frame is not None: - time_frame = f.time_frame.description + for f in similar_features: + if s.time_frame is not None: + time_frame = s.time_frame.description else: time_frame = '' - - + if s.relationship_type is not None and s.feature_to == s.id: + relationship = s.relationship_type + else: + relationship = '' d.append({ 'id': s.id, - 'feature_type': FeatureType.objects.get(pk=s.feature_type_id).name, + 'feature_type': s.feature_type.name, #FeatureType.objects.get(pk=s.feature_type_id).name, 'preferred_name': s.preferred_name, 'similarity': s.similarity, 'distance': s.distance, 'time_frame': time_frame, 'is_primary': s.is_primary, - 'relationship': '' #TODO: query db for relation between id and s.id - if exists, return relation_type as string, else return empty string. + 'relationship': relationship }) return render_to_json_response(d) @@ -134,10 +135,16 @@ def add_relation(request): relation = request.GET.get("relation", None) if feature1 == None or feature2 == None or relation == None: #TODO: split up errors :/ -- not imp. return render_to_json_response({'error': 'bad request'}) + if not request.user.is_staff: return render_to_json_response({'error': 'insufficient permissions error. try logging in again? are you staff / admin?'}) - #TODO: handle saving m2m between feature1 and feature2 with relation. If relation='', either remove existing relation between feature1 and feature2, or ignore if no such existing relation exists. BIG QUESTION: Here it can also deal with is_primary logic - if it sets stuff to is_primary or not, though, this needs to be conveyed to the front-end / a logic figured out to toggle the check-boxes display. + feature1 = get_object_or_404_json(Feature, feature1) + feature2 = get_object_or_404_json(Feature, feature2) + Relationship(feature_from=feature1, feature_to=feature2, relationship_type=relation).save() + if relation == "subsumes": + feature2.is_primary = False + feature2.save() return render_to_json_response({'success': 'relation made successfully.'})