diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-06-13 19:27:36 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-06-13 19:27:36 +0200 | 
| commit | 0bf5c78b91661144b464d004570313c94eeebaaa (patch) | |
| tree | 33e1067fb49787e5bdc704d3d2852d3784a074a2 | |
| parent | e4258578c8a6280e9a8a46f78310b8ee51069c6a (diff) | |
| download | Ishtar-0bf5c78b91661144b464d004570313c94eeebaaa.tar.bz2 Ishtar-0bf5c78b91661144b464d004570313c94eeebaaa.zip | |
Manage use of search indexes for data fields
| -rw-r--r-- | archaeological_operations/tests.py | 20 | ||||
| -rw-r--r-- | ishtar_common/migrations/0060_auto_20180613_1848.py | 25 | ||||
| -rw-r--r-- | ishtar_common/models.py | 24 | 
3 files changed, 69 insertions, 0 deletions
| diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index d1c4892bf..a50681667 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -1259,6 +1259,26 @@ class OperationTest(TestCase, OperationInitTest):          self.assertIn('class="card sheet"', response.content)          self.assertNotIn(u"Marmotte".encode('utf-8'), response.content) +    def test_json_search_vector_update(self): +        operation = self.operations[0] +        content_type = ContentType.objects.get_for_model(operation) +        JsonDataField.objects.create(name=u"Nom de marmotte", +                                     key='groundhog__name', +                                     content_type=content_type, +                                     search_index=True) +        JsonDataField.objects.create(name=u"Numéro grenouille", +                                     key='frog_number', +                                     content_type=content_type) +        operation = models.Operation.objects.get(pk=operation.pk) +        operation.data = {"groundhog": {"name": u"La Marmotte héhé", +                                        "color": u"Red"}, +                          "frog_number": 32303} +        operation.save() +        for key in ('marmott',): +            self.assertIn(key, operation.search_vector) +        for key in ('32303', 'red', 'Red'): +            self.assertNotIn(key, operation.search_vector) +  class CustomFormTest(TestCase, OperationInitTest):      fixtures = FILE_FIXTURES diff --git a/ishtar_common/migrations/0060_auto_20180613_1848.py b/ishtar_common/migrations/0060_auto_20180613_1848.py new file mode 100644 index 000000000..d8fee7c22 --- /dev/null +++ b/ishtar_common/migrations/0060_auto_20180613_1848.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-06-13 18:48 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0059_migrate_importers'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='jsondatafield', +            name='search_index', +            field=models.BooleanField(default=False, verbose_name='Use in search indexes'), +        ), +        migrations.AlterField( +            model_name='document', +            name='authors', +            field=models.ManyToManyField(related_name='documents', to='ishtar_common.Author', verbose_name='Authors'), +        ), +    ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 02c19e011..3d8057c9f 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -45,6 +45,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError  from django.core.files.uploadedfile import SimpleUploadedFile  from django.core.urlresolvers import reverse, NoReverseMatch  from django.core.validators import validate_slug +from django.db import connection  from django.db.models import Q, Max, Count  from django.db.models.signals import post_save, post_delete, m2m_changed  from django.db.utils import DatabaseError @@ -1004,6 +1005,8 @@ class JsonDataField(models.Model):      value_type = models.CharField(_(u"Type"), default="T", max_length=10,                                    choices=JSON_VALUE_TYPES)      order = models.IntegerField(_(u"Order"), default=10) +    search_index = models.BooleanField(_(u"Use in search indexes"), +                                       default=False)      section = models.ForeignKey(JsonDataSection, blank=True, null=True)      custom_forms = models.ManyToManyField(          "CustomForm", blank=True, through="CustomFormJsonField") @@ -1158,6 +1161,27 @@ class FullSearch(models.Model):                      q.all()[0]['search'].decode('utf-8')                  )              ) + +        if hasattr(self, 'data') and self.data: +            content_type = ContentType.objects.get_for_model(self) +            datas = [] +            for json_field in JsonDataField.objects.filter( +                    content_type=content_type, +                    search_index=True).all(): +                data = copy.deepcopy(self.data) +                no_data = False +                for key in json_field.key.split('__'): +                    if key not in data: +                        no_data = True +                        break +                    data = data[key] +                if no_data: +                    continue +                with connection.cursor() as cursor: +                    cursor.execute("SELECT to_tsvector(%s)", +                                   [data]) +                    row = cursor.fetchone() +                    search_vectors.append(row[0])          self.search_vector = merge_tsvectors(search_vectors)          changed = old_search != self.search_vector          if save and changed: | 
