Projet

Général

Profil

0002-authentic2-add-full-text-search-to-AttributeValue-49.patch

Benjamin Dauvergne, 16 janvier 2021 19:18

Télécharger (5,61 ko)

Voir les différences:

Subject: [PATCH 2/4] authentic2: add full text search to AttributeValue
 (#49957)

 src/authentic2/managers.py                    |  4 ++
 .../0031_add_search_vector_to_attributes.py   | 45 +++++++++++++++++++
 .../0032_initialize_search_vectors.py         | 19 ++++++++
 src/authentic2/models.py                      |  6 +++
 4 files changed, 74 insertions(+)
 create mode 100644 src/authentic2/migrations/0031_add_search_vector_to_attributes.py
 create mode 100644 src/authentic2/migrations/0032_initialize_search_vectors.py
src/authentic2/managers.py
23 23
from django.utils.timezone import now
24 24
from django.conf import settings
25 25
from django.contrib.contenttypes.models import ContentType
26
from django.contrib.postgres.search import SearchVector
26 27

  
27 28
from django_rbac.utils import get_ou_model
28 29
from model_utils import managers
......
86 87
            raise AttributeValue.DoesNotExist
87 88
        return self.get(content_type=ct, object_id=owner.pk, attribute=at)
88 89

  
90
    def update_search_vectors(self):
91
        self.update(search_vector=SearchVector('content'))
92

  
89 93

  
90 94
class ServiceQuerySet(managers.InheritanceQuerySetMixin, GetBySlugQuerySet):
91 95
    pass
src/authentic2/migrations/0031_add_search_vector_to_attributes.py
1
import django.contrib.postgres.indexes
2
import django.contrib.postgres.search
3
from django.db import migrations
4

  
5

  
6
def create_trigger(apps, schema_editor):
7
    with schema_editor.connection.cursor() as cursor:
8
        cursor.execute('SHOW default_text_search_config')
9
        default_text_search_config, = cursor.fetchone()
10
        cursor.execute('''CREATE OR REPLACE FUNCTION authentic2_update_atv_search_vector() RETURNS TRIGGER AS $$
11
BEGIN
12
    IF TG_OP = 'INSERT' OR (TG_OP = 'UPDATE' AND NEW.content <> OLD.content) THEN
13
        NEW.search_vector = to_tsvector(NEW.content);
14
    END IF;
15
    RETURN NEW;
16
END; $$ LANGUAGE plpgsql''')
17
        cursor.execute('''CREATE TRIGGER authentic2_attributevalue_search_vector_trigger
18
BEFORE INSERT OR UPDATE OF content
19
ON authentic2_attributevalue
20
FOR EACH ROW EXECUTE PROCEDURE authentic2_update_atv_search_vector()''')
21

  
22

  
23
def drop_trigger(apps, schema_editor):
24
    with schema_editor.connection.cursor() as cursor:
25
        cursor.execute('DROP TRIGGER authentic2_attributevalue_search_vector_trigger')
26

  
27

  
28
class Migration(migrations.Migration):
29
    dependencies = [
30
        ('authentic2', '0030_clean_admin_tools_tables'),
31
    ]
32

  
33
    operations = [
34
        migrations.AddField(
35
            model_name='attributevalue',
36
            name='search_vector',
37
            field=django.contrib.postgres.search.SearchVectorField(editable=False, null=True),
38
        ),
39
        migrations.AddIndex(
40
            model_name='attributevalue',
41
            index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='authentic2_atv_tsvector_idx')
42
        ),
43
        migrations.RunPython(create_trigger, drop_trigger),
44

  
45
    ]
src/authentic2/migrations/0032_initialize_search_vectors.py
1
# Generated by Django 2.2.17 on 2021-01-16 14:22
2

  
3
from django.contrib.postgres.search import SearchVector
4
from django.db import migrations
5

  
6

  
7
def initialize_search_vector(apps, schema_editor):
8
    AttributeValue = apps.get_model('authentic2', 'AttributeValue')
9
    AttributeValue.all_objects.update(search_vector=SearchVector('content'))
10

  
11

  
12
class Migration(migrations.Migration):
13
    dependencies = [
14
        ('authentic2', '0031_add_search_vector_to_attributes'),
15
    ]
16

  
17
    operations = [
18
        migrations.RunPython(initialize_search_vector, reverse_code=migrations.RunPython.noop),
19
    ]
src/authentic2/models.py
29 29
from django.core.exceptions import ValidationError
30 30
from django.contrib.contenttypes.models import ContentType
31 31
from django.contrib.postgres.fields import jsonb
32
from django.contrib.postgres.search import SearchVectorField
33
from django.contrib.postgres.indexes import GinIndex
32 34

  
33 35
from model_utils.managers import QueryManager
34 36

  
......
319 321
        multiple = models.BooleanField(default=False, null=True)
320 322

  
321 323
    content = models.TextField(verbose_name=_('content'), db_index=True)
324
    search_vector = SearchVectorField(null=True, editable=False)
322 325
    verified = models.BooleanField(default=False)
323 326

  
324 327
    all_objects = managers.AttributeValueManager()
......
341 344
        unique_together = (
342 345
            ('content_type', 'object_id', 'attribute', 'multiple', 'content'),
343 346
        )
347
        indexes = [
348
            GinIndex(fields=['search_vector'], name='authentic2_atv_tsvector_idx'),
349
        ]
344 350

  
345 351

  
346 352
class PasswordReset(models.Model):
347
-