authentic2: add full text search to AttributeValue (#49957)

This commit is contained in:
Benjamin Dauvergne 2021-01-16 15:33:45 +01:00
parent 3cb60a412f
commit c98b0f2347
5 changed files with 73 additions and 0 deletions

View File

@ -23,6 +23,7 @@ from django.db.models.query import QuerySet
from django.utils.timezone import now
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.search import SearchVector
from django_rbac.utils import get_ou_model
from model_utils import managers

View File

@ -0,0 +1,46 @@
import django.contrib.postgres.indexes
import django.contrib.postgres.search
from django.db import migrations
def create_trigger(apps, schema_editor):
with schema_editor.connection.cursor() as cursor:
cursor.execute('SHOW default_text_search_config')
default_text_search_config, = cursor.fetchone()
cursor.execute('''CREATE OR REPLACE FUNCTION authentic2_update_atv_search_vector() RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'INSERT' OR (TG_OP = 'UPDATE' AND NEW.content <> OLD.content) THEN
NEW.search_vector = to_tsvector(NEW.content);
END IF;
RETURN NEW;
END; $$ LANGUAGE plpgsql''')
cursor.execute('''CREATE TRIGGER authentic2_attributevalue_search_vector_trigger
BEFORE INSERT OR UPDATE OF content
ON authentic2_attributevalue
FOR EACH ROW EXECUTE PROCEDURE authentic2_update_atv_search_vector()''')
def drop_trigger(apps, schema_editor):
with schema_editor.connection.cursor() as cursor:
cursor.execute('DROP TRIGGER IF EXISTS authentic2_attributevalue_search_vector_trigger ON authentic2_attributevalue')
cursor.execute('DROP FUNCTION IF EXISTS authentic2_update_atv_search_vector')
class Migration(migrations.Migration):
dependencies = [
('authentic2', '0030_clean_admin_tools_tables'),
]
operations = [
migrations.AddField(
model_name='attributevalue',
name='search_vector',
field=django.contrib.postgres.search.SearchVectorField(editable=False, null=True),
),
migrations.AddIndex(
model_name='attributevalue',
index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='authentic2_atv_tsvector_idx')
),
migrations.RunPython(create_trigger, drop_trigger),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.17 on 2021-01-16 14:22
from django.contrib.postgres.search import SearchVector
from django.db import migrations
def initialize_search_vector(apps, schema_editor):
AttributeValue = apps.get_model('authentic2', 'AttributeValue')
AttributeValue.all_objects.update(search_vector=SearchVector('content'))
class Migration(migrations.Migration):
dependencies = [
('authentic2', '0031_add_search_vector_to_attributes'),
]
operations = [
migrations.RunPython(initialize_search_vector, reverse_code=migrations.RunPython.noop),
]

View File

@ -29,6 +29,8 @@ from django.utils.six.moves.urllib import parse as urlparse
from django.core.exceptions import ValidationError
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import jsonb
from django.contrib.postgres.search import SearchVectorField
from django.contrib.postgres.indexes import GinIndex
from model_utils.managers import QueryManager
@ -319,6 +321,7 @@ class AttributeValue(models.Model):
multiple = models.BooleanField(default=False, null=True)
content = models.TextField(verbose_name=_('content'), db_index=True)
search_vector = SearchVectorField(null=True, editable=False)
verified = models.BooleanField(default=False)
all_objects = managers.AttributeValueManager()
@ -341,6 +344,9 @@ class AttributeValue(models.Model):
unique_together = (
('content_type', 'object_id', 'attribute', 'multiple', 'content'),
)
indexes = [
GinIndex(fields=['search_vector'], name='authentic2_atv_tsvector_idx'),
]
class PasswordReset(models.Model):

View File

@ -120,6 +120,7 @@ class SerializerTests(TestCase):
'content': '0101010101',
'multiple': False,
'verified': False,
'search_vector': None,
}
}
]