feat(library): register IngestJob admin and link Neo4j views
- Add read-only ModelAdmin for IngestJob with filters, search, and date hierarchy for operational visibility - Inject proxy entries into the admin index for Neo4j-backed entities (Libraries, Concepts, Search, Embedding pipeline) that link to existing CRUD views in library/views.py - Makes library content discoverable from /admin/ without pretending neomodel StructuredNodes are Django ORM models
This commit is contained in:
@@ -1,5 +1,123 @@
|
||||
# Library app does not use standard Django admin (neomodel StructuredNodes
|
||||
# are not Django ORM models). Custom admin views are provided as regular
|
||||
# app views in library/views.py, rendered within Themis's template structure.
|
||||
#
|
||||
# The embedding pipeline dashboard is at /library/embedding/
|
||||
"""Admin registrations for the library app.
|
||||
|
||||
Most library content (Library, Collection, Item, Chunk, Concept, Image,
|
||||
ImageEmbedding) lives in Neo4j via neomodel and cannot use Django's
|
||||
standard ModelAdmin. Those entities have full CRUD pages in
|
||||
``library/views.py``; this module wires proxy rows into the admin index
|
||||
so they are discoverable from ``/admin/``.
|
||||
|
||||
``IngestJob`` is a regular Django ORM model and gets a normal,
|
||||
read-only ModelAdmin.
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.urls import NoReverseMatch, reverse
|
||||
|
||||
from .models import IngestJob
|
||||
|
||||
|
||||
@admin.register(IngestJob)
|
||||
class IngestJobAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"status",
|
||||
"library_uid",
|
||||
"item_uid",
|
||||
"source",
|
||||
"source_ref",
|
||||
"progress",
|
||||
"retry_count",
|
||||
"created_at",
|
||||
"completed_at",
|
||||
)
|
||||
list_filter = ("status", "source", "created_at")
|
||||
search_fields = (
|
||||
"id",
|
||||
"library_uid",
|
||||
"item_uid",
|
||||
"source_ref",
|
||||
"content_hash",
|
||||
"title",
|
||||
"celery_task_id",
|
||||
)
|
||||
date_hierarchy = "created_at"
|
||||
ordering = ("-created_at",)
|
||||
readonly_fields = (
|
||||
"id",
|
||||
"item_uid",
|
||||
"library_uid",
|
||||
"celery_task_id",
|
||||
"status",
|
||||
"progress",
|
||||
"error",
|
||||
"retry_count",
|
||||
"chunks_created",
|
||||
"concepts_extracted",
|
||||
"embedding_model",
|
||||
"content_hash",
|
||||
"source",
|
||||
"source_ref",
|
||||
"s3_key",
|
||||
"title",
|
||||
"file_type",
|
||||
"file_size",
|
||||
"collection_uid",
|
||||
"created_at",
|
||||
"started_at",
|
||||
"completed_at",
|
||||
)
|
||||
|
||||
def has_add_permission(self, request):
|
||||
return False
|
||||
|
||||
def has_change_permission(self, request, obj=None):
|
||||
# View-only; superusers can still open the detail page.
|
||||
return request.method in ("GET", "HEAD")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Neo4j-resident entities: proxy entries on the admin index that link to the
|
||||
# existing CRUD views in library/views.py. No shim models — just an honest
|
||||
# signpost so /admin/ doesn't pretend the library is empty.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
_NEO4J_ADMIN_LINKS = [
|
||||
("Libraries", "library:library-list"),
|
||||
("Concepts", "library:concept-list"),
|
||||
("Search", "library:search"),
|
||||
("Embedding pipeline", "library:embedding-dashboard"),
|
||||
]
|
||||
|
||||
|
||||
_original_get_app_list = admin.site.get_app_list
|
||||
|
||||
|
||||
def _get_app_list_with_library_links(request, app_label=None):
|
||||
app_list = _original_get_app_list(request, app_label)
|
||||
for app in app_list:
|
||||
if app["app_label"] != "library":
|
||||
continue
|
||||
for name, url_name in _NEO4J_ADMIN_LINKS:
|
||||
try:
|
||||
url = reverse(url_name)
|
||||
except NoReverseMatch:
|
||||
continue
|
||||
app["models"].append(
|
||||
{
|
||||
"name": name,
|
||||
"object_name": name,
|
||||
"perms": {
|
||||
"add": False,
|
||||
"change": True,
|
||||
"delete": False,
|
||||
"view": True,
|
||||
},
|
||||
"admin_url": url,
|
||||
"add_url": None,
|
||||
"view_only": True,
|
||||
}
|
||||
)
|
||||
return app_list
|
||||
|
||||
|
||||
admin.site.get_app_list = _get_app_list_with_library_links
|
||||
|
||||
Reference in New Issue
Block a user