Skip to content

admin

log_panel.admin

LogAdmin

Bases: ModelAdmin

Read-only admin interface for browsing application logs.

Provides two views: - Cards view (default): one card per logger with error/warning badges and a color-coded timeline strip across the selected time range. - Table view: standard Django changelist with filters and search, shown when any admin filter or search parameter is present.

changelist_view(request, extra_context=None)

Show the cards dashboard unless Django admin filters/search are active.

Source code in log_panel/admin.py
def changelist_view(
    self, request: HttpRequest, extra_context: dict | None = None
) -> HttpResponse:
    """Show the cards dashboard unless Django admin filters/search are active."""
    if set(request.GET.keys()).issubset(CARDS_PARAMS):
        backend: LogsBackend | None = conf.get_backend()
        context: dict = self._logger_cards_context(request, backend, error=None)
        return TemplateResponse(
            request, "admin/log_panel/panel/cards.html", context
        )

    self.list_per_page: Any = conf.get_setting(
        key="TABLE_PAGE_SIZE"
    )  # pragma: no cover
    return super().changelist_view(request, extra_context)  # pragma: no cover

get_urls()

Add a read-only full-message view for chunked log payloads.

Source code in log_panel/admin.py
def get_urls(self) -> list:
    """Add a read-only full-message view for chunked log payloads."""
    return [
        path(
            "<path:object_id>/message/",
            self.admin_site.admin_view(self.message_view),
            name="log_panel_log_message",
        ),
        *super().get_urls(),
    ]

message_view(request, object_id)

Render the complete log message for a single log entry.

Source code in log_panel/admin.py
def message_view(self, request: HttpRequest, object_id: str) -> TemplateResponse:
    """Render the complete log message for a single log entry."""
    log: Log = get_object_or_404(
        Log.objects.prefetch_related("message_chunks"),
        pk=object_id,
    )
    return TemplateResponse(
        request,
        "admin/log_panel/panel/message.html",
        {
            **self.admin_site.each_context(request),
            "title": f"{conf.get_setting(key='TITLE')}{log.logger_name}",
            "opts": self.model._meta,
            "log": log,
            "log_message": log.get_full_message(),
            "level_colors": conf.get_level_colors(),
        },
    )

short_message(obj)

Render the message preview with a link to the full payload for chunked entries.

Source code in log_panel/admin.py
@admin.display(description="Message")
def short_message(self, obj: Log) -> str:
    """Render the message preview with a link to the full payload for chunked entries."""
    if obj.message_chunked:
        url: str = reverse(viewname="admin:log_panel_log_message", args=[obj.pk])
        return format_html(
            '{} <a href="{}">&#91;full message ({} chars)&#93;</a>',
            obj.message,
            url,
            obj.message_size,
        )
    return obj.message