diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-09-27 16:25:34 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-09-27 16:25:34 +0200 |
commit | 22cc2e2052a3fca4b4bd21c99b04c8efcfaf4bfa (patch) | |
tree | 949c12ffab83eb3fba5adf04c377d5488d2087d9 | |
parent | ce68857ab707ec1fe744a1007c04c10fdb05e0ed (diff) | |
download | Chimère-22cc2e2052a3fca4b4bd21c99b04c8efcfaf4bfa.tar.bz2 Chimère-22cc2e2052a3fca4b4bd21c99b04c8efcfaf4bfa.zip |
New search management via postgresql
-rw-r--r-- | chimere/migrations/0008_auto_20170927_1539.py | 82 | ||||
-rw-r--r-- | chimere/models.py | 74 | ||||
-rw-r--r-- | chimere/views.py | 4 | ||||
-rw-r--r-- | settings.py | 3 |
4 files changed, 141 insertions, 22 deletions
diff --git a/chimere/migrations/0008_auto_20170927_1539.py b/chimere/migrations/0008_auto_20170927_1539.py new file mode 100644 index 0000000..9cb5e7d --- /dev/null +++ b/chimere/migrations/0008_auto_20170927_1539.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-09-27 15:39 +from __future__ import unicode_literals + +import django.contrib.postgres.search +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('chimere', '0007_auto_20170910_1109'), + ] + + operations = [ + migrations.AddField( + model_name='marker', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto filled at save', null=True, verbose_name='Search vector'), + ), + migrations.AddField( + model_name='polygon', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto filled at save', null=True, verbose_name='Search vector'), + ), + migrations.AddField( + model_name='property', + name='search_value', + field=models.TextField(blank=True, help_text='Auto filled at save', null=True, verbose_name='Search value'), + ), + migrations.AddField( + model_name='route', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto filled at save', null=True, verbose_name='Search vector'), + ), + migrations.AlterField( + model_name='area', + name='default_subcategories', + field=models.ManyToManyField(blank=True, to='chimere.SubCategory', verbose_name='Sub-categories checked by default'), + ), + migrations.AlterField( + model_name='area', + name='layers', + field=models.ManyToManyField(blank=True, related_name='areas', through='chimere.AreaLayers', to='chimere.Layer'), + ), + migrations.AlterField( + model_name='area', + name='overlays', + field=models.ManyToManyField(blank=True, related_name='overlays', through='chimere.AreaOverlays', to='chimere.Overlay'), + ), + migrations.AlterField( + model_name='area', + name='subcategories', + field=models.ManyToManyField(blank=True, db_table='chimere_subcategory_areas', help_text='If no sub-category is set all sub-categories are available', related_name='areas', to='chimere.SubCategory', verbose_name='Restricted to theses sub-categories'), + ), + migrations.AlterField( + model_name='property', + name='marker', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='properties', to='chimere.Marker', verbose_name='Point of interest'), + ), + migrations.AlterField( + model_name='property', + name='polygon', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='properties', to='chimere.Polygon', verbose_name='Polygon'), + ), + migrations.AlterField( + model_name='property', + name='route', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='properties', to='chimere.Route', verbose_name='Route'), + ), + migrations.AlterField( + model_name='propertymodel', + name='areas', + field=models.ManyToManyField(blank=True, help_text='If no area is set the property apply to all areas', to='chimere.Area', verbose_name='Restrict to theses areas'), + ), + migrations.AlterField( + model_name='propertymodel', + name='subcategories', + field=models.ManyToManyField(blank=True, help_text='If no sub-category is set all the property applies to all sub-categories', related_name='properties', to='chimere.SubCategory', verbose_name='Restricted to theses sub-categories'), + ), + ] diff --git a/chimere/models.py b/chimere/models.py index d8bf638..7cf911a 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -38,6 +38,7 @@ from django import forms from django.conf import settings from django.contrib.auth.models import User, Permission, ContentType, Group from django.contrib.gis.db import models +from django.contrib.postgres.search import SearchVectorField, SearchVector from django.core.files import File from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse @@ -603,6 +604,8 @@ class GeographicItem(models.Model): _("Normalised weight"), blank=True, null=True, help_text=_("The weight normalised to be between 0 and 1. " "Automatically recalculated.")) + search_vector = SearchVectorField(_("Search vector"), blank=True, null=True, + help_text=_("Auto filled at save")) class Meta: abstract = True @@ -1071,22 +1074,39 @@ def geometry_post_save(pre_save_geom_values): or kwargs['instance'].pk not in pre_save_geom_values: return instance = kwargs['instance'] + changed = False + pre = pre_save_geom_values[instance.pk] # force the reinit of modified_since_import - if pre['modified_since_import'] != instance.modified_since_import: - return - if (instance.import_version != pre['import_version'] - and instance.modified_since_import): - instance.modified_since_import = False - instance.save() - return - if instance.modified_since_import: - return - if [key for key in pre if pre not in ( - 'import_version', 'modified_since_import') and - getattr(instance, key) != pre[key]]: - instance.modified_since_import = True + if pre['modified_since_import'] == instance.modified_since_import: + if (instance.import_version != pre['import_version'] + and instance.modified_since_import): + instance.modified_since_import = False + changed = True + elif not instance.modified_since_import and \ + [key for key in pre if pre not in ( + 'import_version', 'modified_since_import') and + getattr(instance, key) != pre[key]]: + instance.modified_since_import = True + changed = True + + if not getattr(instance, '_search_updated', None): + instance._search_updated = True + q = instance.__class__.objects.filter(pk=instance.pk) + q = q.annotate( + search=SearchVector( + 'name', 'description', + 'keywords', + 'categories__keywords', + 'properties__search_value', + config=settings.CHIMERE_SEARCH_LANGUAGE + )) + instance.search_vector = q.all()[0].search + changed = True + + if changed: instance.save() + return geom_post_save @@ -2116,8 +2136,9 @@ class PropertyModel(models.Model): return self.slug def getNamedId(self): - '''Get the name used as named id (easily sortable) - ''' + """ + Get the name used as named id (easily sortable) + """ return 'property_%d_%d' % (self.order, self.id) @classmethod @@ -2153,17 +2174,26 @@ class PropertyModelChoice(models.Model): class Property(models.Model): - '''Property for a POI - ''' + """ + Property for a POI + """ marker = models.ForeignKey( - Marker, verbose_name=_("Point of interest"), blank=True, null=True) + Marker, verbose_name=_("Point of interest"), blank=True, null=True, + related_name='properties' + ) route = models.ForeignKey( - Route, verbose_name=_("Route"), blank=True, null=True) + Route, verbose_name=_("Route"), blank=True, null=True, + related_name='properties' + ) polygon = models.ForeignKey( - Polygon, verbose_name=_("Polygon"), blank=True, null=True) + Polygon, verbose_name=_("Polygon"), blank=True, null=True, + related_name='properties' + ) propertymodel = models.ForeignKey(PropertyModel, verbose_name=_("Property model")) value = models.TextField(_("Value")) + search_value = models.TextField(_("Search value"), blank=True, null=True, + help_text=_("Auto filled at save")) def __str__(self): if self.propertymodel.type == 'C': @@ -2194,3 +2224,7 @@ class Property(models.Model): return None else: return self.value + + def save(self, *args, **kwargs): + self.search_value = str(self.python_value or "") + super(Property, self).save(*args, **kwargs) diff --git a/chimere/views.py b/chimere/views.py index 3070132..7a1ff66 100644 --- a/chimere/views.py +++ b/chimere/views.py @@ -864,9 +864,9 @@ def get_all_categories(request, area_name=None): def get_available_categories(request, area_name=None, area=None, status='A', force=None): - ''' + """ Get category menu for a designed area - ''' + """ context_data, redir = get_base_response(request, area_name) area = context_data["area"] if redir: diff --git a/settings.py b/settings.py index 02200fb..cc5ed21 100644 --- a/settings.py +++ b/settings.py @@ -142,6 +142,8 @@ CHIMERE_THUMBS_SCALE_WIDTH = None # search engine CHIMERE_SEARCH_ENGINE = False +CHIMERE_SEARCH_LANGUAGE = 'french' + HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.solr_backend.SolrEngine', @@ -253,6 +255,7 @@ INSTALLED_APPS = [ 'django.contrib.sites', 'django.contrib.gis', 'django.contrib.staticfiles', + 'django.contrib.postgres', ] # celery |