summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorPaolo Melchiorre <paolo@melchiorre.org>2025-09-20 03:59:28 +0200
committerGitHub <noreply@github.com>2025-09-19 21:59:28 -0400
commit52217c861cf873536a383d394eaa188f7c3b32a5 (patch)
tree656e9aebaed6a89bbcd3b1c95307c51631dcc22c /docs
parentb1eb535f63f6770296d3b19e8d1ca3188ee9221a (diff)
Replaced search field with generated vector field (#2192)
Diffstat (limited to 'docs')
-rw-r--r--docs/management/commands/update_docs.py24
-rw-r--r--docs/management/commands/update_index.py28
-rw-r--r--docs/migrations/0007_add_docs_search_vector.py1658
-rw-r--r--docs/models.py59
-rw-r--r--docs/search.py20
-rw-r--r--docs/tests/test_models.py19
-rw-r--r--docs/tests/test_views.py1
7 files changed, 1707 insertions, 102 deletions
diff --git a/docs/management/commands/update_docs.py b/docs/management/commands/update_docs.py
index 785a406f..d1f3df04 100644
--- a/docs/management/commands/update_docs.py
+++ b/docs/management/commands/update_docs.py
@@ -48,13 +48,6 @@ class Command(BaseCommand):
help="Ask before building each version",
)
parser.add_argument(
- "--update-index",
- action="store_true",
- dest="update_index",
- default=False,
- help="Also update the search vector field.",
- )
- parser.add_argument(
"--purge-cache",
action="store_true",
dest="purge_cache",
@@ -98,7 +91,6 @@ class Command(BaseCommand):
def handle(self, *versions, **kwargs):
self.verbosity = kwargs["verbosity"]
- self.update_index = kwargs["update_index"]
self.purge_cache = kwargs["purge_cache"]
self.default_builders = ["json", "djangohtml"]
@@ -106,17 +98,12 @@ class Command(BaseCommand):
# Keep track of which Git sources have been updated, e.g.,
# {'1.8': True} if the 1.8 docs updated.
self.release_docs_changed = {}
- # Only update the index if some docs rebuild.
- self.update_index_required = False
for release in self._get_doc_releases(versions, kwargs):
self.build_doc_release(
release, force=kwargs["force"], interactive=kwargs["interactive"]
)
- if self.update_index_required:
- call_command("update_index", **{"verbosity": self.verbosity})
-
if self.purge_cache:
changed_versions = {
version
@@ -172,8 +159,6 @@ class Command(BaseCommand):
)
return
- self.update_index_required = self.update_index
-
source_dir = checkout_dir.joinpath("docs")
if release.lang != "en":
@@ -288,15 +273,6 @@ class Command(BaseCommand):
if release.is_default:
self._setup_stable_symlink(release, built_dir)
- #
- # Rebuild the imported document list and search index.
- #
- if not self.update_index:
- return
-
- if self.verbosity >= 2:
- self.stdout.write(" reindexing...")
-
json_built_dir = parent_build_dir.joinpath("_built", "json")
documents = gen_decoded_documents(json_built_dir)
release.sync_to_db(documents)
diff --git a/docs/management/commands/update_index.py b/docs/management/commands/update_index.py
deleted file mode 100644
index 86d80803..00000000
--- a/docs/management/commands/update_index.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import time
-
-from django.core.management.base import BaseCommand
-from django.db import transaction
-
-from ...models import Document
-
-
-class Command(BaseCommand):
-
- def handle(self, *args, **options):
- """
- Update Document's search vector field in an atomic transaction.
-
- Inside an atomic transaction all not null search vector values are set
- to null and than the field are updated using the document definition.
- """
- _started_at = time.time()
- with transaction.atomic():
- Document.objects.search_reset()
- updated_documents = Document.objects.search_update()
- elapsed = time.time() - _started_at
- if options["verbosity"] >= 1:
- self.stdout.write(
- self.style.SUCCESS(
- f"Indexed {updated_documents} documents in {elapsed:.03}s."
- )
- )
diff --git a/docs/migrations/0007_add_docs_search_vector.py b/docs/migrations/0007_add_docs_search_vector.py
new file mode 100644
index 00000000..1834ef66
--- /dev/null
+++ b/docs/migrations/0007_add_docs_search_vector.py
@@ -0,0 +1,1658 @@
+# Generated by Django 5.2 on 2025-09-14 15:00
+
+import django.contrib.postgres.indexes
+import django.contrib.postgres.search
+import django.db.models.fields.json
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("docs", "0006_alter_document_metadata_noop"),
+ ]
+
+ operations = [
+ migrations.RemoveIndex(
+ model_name="document",
+ name="docs_docume_search_5dc895_gin",
+ ),
+ migrations.RemoveField(
+ model_name="document",
+ name="search",
+ ),
+ migrations.AddField(
+ model_name="document",
+ name="search_vector",
+ field=models.GeneratedField(
+ db_persist=True,
+ expression=models.Case(
+ models.When(
+ config="arabic",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="arabic", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="arabic",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "arabic"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="arabic",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "arabic"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="arabic",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("arabic"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="arabic",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("arabic"),
+ ),
+ ),
+ models.When(
+ config="catalan",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="catalan", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="catalan",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "catalan"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="catalan",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "catalan"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="catalan",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("catalan"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="catalan",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("catalan"),
+ ),
+ ),
+ models.When(
+ config="danish",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="danish", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="danish",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "danish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="danish",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "danish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="danish",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("danish"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="danish",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("danish"),
+ ),
+ ),
+ models.When(
+ config="german",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="german", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="german",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "german"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="german",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "german"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="german",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("german"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="german",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("german"),
+ ),
+ ),
+ models.When(
+ config="greek",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="greek", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="greek",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "greek"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="greek",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "greek"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="greek",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("greek"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="greek",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("greek"),
+ ),
+ ),
+ models.When(
+ config="english",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="english", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="english",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "english"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="english",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "english"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="english",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("english"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="english",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("english"),
+ ),
+ ),
+ models.When(
+ config="spanish",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="spanish", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="spanish",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "spanish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="spanish",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "spanish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="spanish",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("spanish"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="spanish",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("spanish"),
+ ),
+ ),
+ models.When(
+ config="basque",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="basque", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="basque",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "basque"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="basque",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "basque"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="basque",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("basque"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="basque",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("basque"),
+ ),
+ ),
+ models.When(
+ config="finnish",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="finnish", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="finnish",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "finnish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="finnish",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "finnish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="finnish",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("finnish"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="finnish",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("finnish"),
+ ),
+ ),
+ models.When(
+ config="french",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="french", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="french",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "french"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="french",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "french"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="french",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("french"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="french",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("french"),
+ ),
+ ),
+ models.When(
+ config="irish",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="irish", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="irish",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "irish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="irish",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "irish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="irish",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("irish"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="irish",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("irish"),
+ ),
+ ),
+ models.When(
+ config="hindi",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="hindi", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="hindi",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "hindi"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="hindi",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "hindi"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="hindi",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("hindi"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="hindi",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("hindi"),
+ ),
+ ),
+ models.When(
+ config="hungarian",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="hungarian", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="hungarian",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "hungarian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="hungarian",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "hungarian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="hungarian",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "hungarian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="hungarian",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("hungarian"),
+ ),
+ ),
+ models.When(
+ config="armenian",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="armenian", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="armenian",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "armenian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="armenian",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "armenian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="armenian",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("armenian"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="armenian",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("armenian"),
+ ),
+ ),
+ models.When(
+ config="indonesian",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="indonesian", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="indonesian",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "indonesian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="indonesian",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "indonesian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="indonesian",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "indonesian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="indonesian",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("indonesian"),
+ ),
+ ),
+ models.When(
+ config="italian",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="italian", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="italian",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "italian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="italian",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "italian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="italian",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("italian"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="italian",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("italian"),
+ ),
+ ),
+ models.When(
+ config="lithuanian",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="lithuanian", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="lithuanian",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "lithuanian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="lithuanian",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "lithuanian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="lithuanian",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "lithuanian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="lithuanian",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("lithuanian"),
+ ),
+ ),
+ models.When(
+ config="nepali",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="nepali", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="nepali",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "nepali"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="nepali",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "nepali"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="nepali",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("nepali"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="nepali",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("nepali"),
+ ),
+ ),
+ models.When(
+ config="dutch",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="dutch", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="dutch",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "dutch"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="dutch",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "dutch"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="dutch",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("dutch"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="dutch",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("dutch"),
+ ),
+ ),
+ models.When(
+ config="norwegian",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="norwegian", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="norwegian",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "norwegian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="norwegian",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "norwegian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="norwegian",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "norwegian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="norwegian",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("norwegian"),
+ ),
+ ),
+ models.When(
+ config="portuguese",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="portuguese", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="portuguese",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "portuguese"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="portuguese",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "portuguese"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="portuguese",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "portuguese"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="portuguese",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("portuguese"),
+ ),
+ ),
+ models.When(
+ config="romanian",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="romanian", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="romanian",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "romanian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="romanian",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "romanian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="romanian",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("romanian"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="romanian",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("romanian"),
+ ),
+ ),
+ models.When(
+ config="russian",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="russian", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="russian",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "russian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="russian",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "russian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="russian",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("russian"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="russian",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("russian"),
+ ),
+ ),
+ models.When(
+ config="serbian",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="serbian", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="serbian",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "serbian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="serbian",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "serbian"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="serbian",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("serbian"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="serbian",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("serbian"),
+ ),
+ ),
+ models.When(
+ config="swedish",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="swedish", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="swedish",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "swedish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="swedish",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "swedish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="swedish",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("swedish"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="swedish",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("swedish"),
+ ),
+ ),
+ models.When(
+ config="tamil",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="tamil", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="tamil",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "tamil"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="tamil",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "tamil"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="tamil",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("tamil"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="tamil",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("tamil"),
+ ),
+ ),
+ models.When(
+ config="turkish",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="turkish", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="turkish",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "turkish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="turkish",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "turkish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="turkish",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("turkish"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="turkish",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("turkish"),
+ ),
+ ),
+ models.When(
+ config="yiddish",
+ then=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="yiddish", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="yiddish",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "yiddish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="yiddish",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "yiddish"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="yiddish",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("yiddish"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="yiddish",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("yiddish"),
+ ),
+ ),
+ default=django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.CombinedSearchVector(
+ django.contrib.postgres.search.SearchVector(
+ "title", config="simple", weight="A"
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "slug", "metadata"
+ ),
+ config="simple",
+ weight="A",
+ ),
+ django.contrib.postgres.search.SearchConfig(
+ "simple"
+ ),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "toc", "metadata"
+ ),
+ config="simple",
+ weight="B",
+ ),
+ django.contrib.postgres.search.SearchConfig("simple"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "body", "metadata"
+ ),
+ config="simple",
+ weight="C",
+ ),
+ django.contrib.postgres.search.SearchConfig("simple"),
+ ),
+ "||",
+ django.contrib.postgres.search.SearchVector(
+ django.db.models.fields.json.KeyTextTransform(
+ "parents", "metadata"
+ ),
+ config="simple",
+ weight="D",
+ ),
+ django.contrib.postgres.search.SearchConfig("simple"),
+ ),
+ ),
+ output_field=django.contrib.postgres.search.SearchVectorField(),
+ ),
+ ),
+ migrations.AlterField(
+ model_name="document",
+ name="config",
+ field=models.SlugField(db_default="simple", default="simple"),
+ ),
+ migrations.AddIndex(
+ model_name="document",
+ index=django.contrib.postgres.indexes.GinIndex(
+ fields=["search_vector"], name="document_search_vector_idx"
+ ),
+ ),
+ migrations.AddConstraint(
+ model_name="document",
+ constraint=models.CheckConstraint(
+ condition=models.Q(
+ (
+ "config__in",
+ [
+ "simple",
+ "arabic",
+ "catalan",
+ "danish",
+ "german",
+ "greek",
+ "english",
+ "spanish",
+ "basque",
+ "finnish",
+ "french",
+ "irish",
+ "hindi",
+ "hungarian",
+ "armenian",
+ "indonesian",
+ "italian",
+ "lithuanian",
+ "nepali",
+ "dutch",
+ "norwegian",
+ "portuguese",
+ "romanian",
+ "russian",
+ "serbian",
+ "swedish",
+ "tamil",
+ "turkish",
+ "yiddish",
+ ],
+ )
+ ),
+ name="document_config_allowed_languages",
+ ),
+ ),
+ ]
diff --git a/docs/models.py b/docs/models.py
index fb6714b9..17c2cca0 100644
--- a/docs/models.py
+++ b/docs/models.py
@@ -16,7 +16,11 @@ from django.contrib.postgres.search import (
)
from django.core.cache import cache
from django.db import models, transaction
-from django.db.models import Q
+from django.db.models import (
+ Case,
+ Q,
+ When,
+)
from django.db.models.fields.json import KeyTextTransform
from django.utils.functional import cached_property
from django.utils.html import strip_tags
@@ -27,10 +31,10 @@ from releases.models import Release
from . import utils
from .search import (
DEFAULT_TEXT_SEARCH_CONFIG,
- DOCUMENT_SEARCH_VECTOR,
START_SEL,
STOP_SEL,
TSEARCH_CONFIG_LANGUAGES,
+ get_document_search_vector,
)
@@ -261,7 +265,7 @@ class DocumentQuerySet(models.QuerySet):
search_query = SearchQuery(
query_text, config=models.F("config"), search_type="websearch"
)
- search_rank = SearchRank(models.F("search"), search_query)
+ search_rank = SearchRank(models.F("search_vector"), search_query)
search = partial(
SearchHeadline,
start_sel=START_SEL,
@@ -296,7 +300,7 @@ class DocumentQuerySet(models.QuerySet):
)
vector_qs = (
base_qs.alias(rank=search_rank)
- .filter(search=search_query)
+ .filter(search_vector=search_query)
.order_by("-rank")
)
if not vector_qs:
@@ -314,22 +318,6 @@ class DocumentQuerySet(models.QuerySet):
else:
return self.none()
- def search_reset(self):
- """Set to null all not null Document's search vector fields."""
- return Document.objects.exclude(search=None).update(search=None)
-
- def search_update(self):
- """
- Update Document's search vector fields using the document definition.
-
- This method don't index the module pages (since source code is hard to
- combine with full text search) and the big flattened index of the CBVs.
- """
- return Document.objects.exclude(
- Q(path__startswith="_modules")
- | Q(path__startswith="ref/class-based-views/flattened-index")
- ).update(search=DOCUMENT_SEARCH_VECTOR)
-
class Document(models.Model):
"""
@@ -344,17 +332,42 @@ class Document(models.Model):
path = models.CharField(max_length=500)
title = models.CharField(max_length=500)
metadata = models.JSONField(default=dict)
- search = SearchVectorField(null=True, editable=False)
- config = models.SlugField(default=DEFAULT_TEXT_SEARCH_CONFIG)
+ # Use Case/When to force the expression to be immutable, per:
+ # https://www.paulox.net/2025/09/08/djangocon-us-2025/
+ search_vector = models.GeneratedField(
+ expression=Case(
+ *[
+ When(config=lang, then=get_document_search_vector(lang))
+ for lang in TSEARCH_CONFIG_LANGUAGES.values()
+ ],
+ default=get_document_search_vector(),
+ ),
+ output_field=SearchVectorField(),
+ db_persist=True,
+ )
+ config = models.SlugField(
+ db_default=DEFAULT_TEXT_SEARCH_CONFIG, default=DEFAULT_TEXT_SEARCH_CONFIG
+ )
objects = DocumentQuerySet.as_manager()
class Meta:
+ constraints = [
+ models.CheckConstraint(
+ condition=Q(
+ config__in=[
+ DEFAULT_TEXT_SEARCH_CONFIG,
+ *TSEARCH_CONFIG_LANGUAGES.values(),
+ ]
+ ),
+ name="document_config_allowed_languages",
+ )
+ ]
indexes = [
models.Index(
fields=["release", "title"], name="document_release_title_idx"
),
- GinIndex(fields=["search"]),
+ GinIndex(fields=["search_vector"], name="document_search_vector_idx"),
]
unique_together = ("release", "path")
diff --git a/docs/search.py b/docs/search.py
index 1a2ebcaa..3a99978d 100644
--- a/docs/search.py
+++ b/docs/search.py
@@ -1,5 +1,5 @@
from django.contrib.postgres.search import SearchVector
-from django.db.models import F, TextChoices
+from django.db.models import TextChoices
from django.db.models.fields.json import KeyTextTransform
from django.utils.translation import gettext_lazy as _
@@ -40,15 +40,17 @@ TSEARCH_CONFIG_LANGUAGES = {
# https://github.com/postgres/postgres/blob/REL_14_STABLE/src/bin/initdb/initdb.c#L2557
DEFAULT_TEXT_SEARCH_CONFIG = "simple"
-DOCUMENT_SEARCH_VECTOR = (
- SearchVector("title", weight="A", config=F("config"))
- + SearchVector(KeyTextTransform("slug", "metadata"), weight="A", config=F("config"))
- + SearchVector(KeyTextTransform("toc", "metadata"), weight="B", config=F("config"))
- + SearchVector(KeyTextTransform("body", "metadata"), weight="C", config=F("config"))
- + SearchVector(
- KeyTextTransform("parents", "metadata"), weight="D", config=F("config")
+
+def get_document_search_vector(lang=DEFAULT_TEXT_SEARCH_CONFIG):
+ """Return the search vector with the proper language config."""
+ return (
+ SearchVector("title", weight="A", config=lang)
+ + SearchVector(KeyTextTransform("slug", "metadata"), weight="A", config=lang)
+ + SearchVector(KeyTextTransform("toc", "metadata"), weight="B", config=lang)
+ + SearchVector(KeyTextTransform("body", "metadata"), weight="C", config=lang)
+ + SearchVector(KeyTextTransform("parents", "metadata"), weight="D", config=lang)
)
-)
+
START_SEL = "<mark>"
STOP_SEL = "</mark>"
diff --git a/docs/tests/test_models.py b/docs/tests/test_models.py
index 16f9028a..d17bd4d0 100644
--- a/docs/tests/test_models.py
+++ b/docs/tests/test_models.py
@@ -7,7 +7,7 @@ from django.test import TestCase
from releases.models import Release
-from ..models import DOCUMENT_SEARCH_VECTOR, Document, DocumentRelease
+from ..models import Document, DocumentRelease
class ModelsTests(TestCase):
@@ -350,9 +350,6 @@ class DocumentManagerTest(TestCase):
]
Document.objects.bulk_create(Document(**doc) for doc in documents)
- def setUp(self):
- Document.objects.search_update()
-
def test_search(self):
expected_list = [
(
@@ -415,29 +412,17 @@ class DocumentManagerTest(TestCase):
],
)
- def test_search_reset(self):
- self.assertEqual(Document.objects.exclude(search=None).count(), 6)
- self.assertEqual(Document.objects.search_reset(), 6)
- self.assertEqual(Document.objects.exclude(search=None).count(), 0)
-
- def test_search_update(self):
- self.assertEqual(Document.objects.exclude(search=None).count(), 6)
- self.assertEqual(Document.objects.search_update(), 6)
- self.assertEqual(Document.objects.exclude(search=None).count(), 6)
-
def test_search_highlight_stemmed(self):
# The issue only manifests itself when the defaut search config is not english
with connection.cursor() as cursor:
cursor.execute("SET default_text_search_config TO 'simple'", [])
- doc = self.release.documents.create(
+ self.release.documents.create(
config="english",
path="/",
title="triaging tickets",
metadata={"body": "text containing the word triaging", "breadcrumbs": []},
)
- doc.search = DOCUMENT_SEARCH_VECTOR
- doc.save(update_fields=["search"])
self.assertQuerySetEqual(
Document.objects.search("triaging", self.release),
diff --git a/docs/tests/test_views.py b/docs/tests/test_views.py
index fb5a9474..1b5cb06e 100644
--- a/docs/tests/test_views.py
+++ b/docs/tests/test_views.py
@@ -195,7 +195,6 @@ class SearchFormTestCase(TestCase):
Document.objects.bulk_create(
[Document(**queryset_data), Document(**empty_page_data)]
)
- Document.objects.search_update()
base_url = reverse_with_host(
"document-detail",
host="docs",