diff --git a/src/backend/core/admin.py b/src/backend/core/admin.py index 3d2b0ef7..131b3824 100644 --- a/src/backend/core/admin.py +++ b/src/backend/core/admin.py @@ -1,8 +1,10 @@ """Admin classes and registrations for core app.""" +from django.conf import settings from django.contrib import admin, messages from django.contrib.auth import admin as auth_admin -from django.shortcuts import redirect +from django.core.management import call_command +from django.shortcuts import redirect, render from django.utils.translation import gettext_lazy as _ from treebeard.admin import TreeAdmin @@ -227,3 +229,36 @@ class InvitationAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): obj.issuer = request.user obj.save() + + +@admin.register(models.RunIndexing) +class RunIndexingAdmin(admin.ModelAdmin): + """Admin for running indexing commands.""" + + def changelist_view(self, request, extra_context=None): + """Override to avoid querying the database and handle form submission.""" + if request.method == "POST": + try: + call_command( + "index", + batch_size=int(request.POST.get("batch_size")), + lower_time_bound=request.POST.get("lower_time_bound"), + upper_time_bound=request.POST.get("upper_time_bound"), + crash_safe_mode=request.POST.get("crash_safe_mode"), + ) + messages.success(request, _("Indexing triggered!")) + except Exception as e: + messages.error( + request, + _("Error running indexing command: %(error)s") % {"error": str(e)}, + ) + + return render( + request=request, + template_name="runindexing.html", + context={ + **self.admin_site.each_context(request), + "title": "Run Indexing Command", + "default_batch_size": settings.SEARCH_INDEXER_BATCH_SIZE, + }, + ) diff --git a/src/backend/core/migrations/0032_runindexing.py b/src/backend/core/migrations/0032_runindexing.py new file mode 100644 index 00000000..89023f05 --- /dev/null +++ b/src/backend/core/migrations/0032_runindexing.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.12 on 2026-03-26 16:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0031_clean_onboarding_accesses'), + ] + + operations = [ + migrations.CreateModel( + name='RunIndexing', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'verbose_name': 'Run Indexing', + 'managed': False, + }, + ), + ] diff --git a/src/backend/core/models.py b/src/backend/core/models.py index d1869e13..6ef135bf 100644 --- a/src/backend/core/models.py +++ b/src/backend/core/models.py @@ -2029,3 +2029,13 @@ class Invitation(BaseModel): "partial_update": is_admin_or_owner, "retrieve": is_admin_or_owner, } + + +class RunIndexing(models.Model): + """Proxy model for indexing management in admin.""" + + class Meta: + """Meta options.""" + + managed = False + verbose_name = _("Run Indexing") diff --git a/src/backend/core/templates/runindexing.html b/src/backend/core/templates/runindexing.html new file mode 100644 index 00000000..4c2641a1 --- /dev/null +++ b/src/backend/core/templates/runindexing.html @@ -0,0 +1,43 @@ +{% extends "admin/base_site.html" %} +{% load i18n %} + +{% block content %} + +
+ {% csrf_token %} + +
+ +

+ This command triggers the indexing of all documents within the specified time bound. +

+

+ See docs/commands/index.md for more details. +

+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ +{% endblock %}