From 07fe648b9c48654ae6dd855f328ccfbbc979bed7 Mon Sep 17 00:00:00 2001 From: Oracle Date: Mon, 11 Aug 2025 15:23:12 +0200 Subject: [PATCH] Syntax Highliting and more Moved template looking code in base.admin related to error messages, into an actual template file. New feature: Codearea widget Every JSONField will be highlighted in django-admin with json highlighter --- asyncron/base/admin.py | 58 +++++++++---------- .../asyncron/admin-gather-error-message.html | 31 ++++++++++ .../templates/asyncron/codearea-widget.html | 56 ++++++++++++++++++ asyncron/widgets.py | 22 +++++++ 4 files changed, 136 insertions(+), 31 deletions(-) create mode 100644 asyncron/templates/asyncron/admin-gather-error-message.html create mode 100644 asyncron/templates/asyncron/codearea-widget.html create mode 100644 asyncron/widgets.py diff --git a/asyncron/base/admin.py b/asyncron/base/admin.py index 0b0460c..c2bbc6a 100644 --- a/asyncron/base/admin.py +++ b/asyncron/base/admin.py @@ -1,48 +1,44 @@ from django.contrib import admin, messages -from django.utils.safestring import mark_safe -from django.utils.html import escape +from django.template import loader +from django.forms.fields import JSONField + +from ..widgets import Codearea + import traceback class BaseModelAdmin( admin.ModelAdmin ): + def formfield_for_dbfield( self, db_field, **kwargs ): + formfield = super().formfield_for_dbfield(db_field, **kwargs) + if isinstance( formfield, JSONField ): + formfield.widget = Codearea( language = "json" ) + return formfield + def explain_gather_results( self, request, results, fails_to_show = 2 ): failed = 0 for id, e in results.items(): if isinstance(e, BaseException): failed += 1 if failed <= fails_to_show: + + traceback_message = None if request.user.is_superuser: traceback_message = ''.join(traceback.TracebackException.from_exception(e).format()) - self.message_user( request, mark_safe(f""" - Error For {id}: - -
{escape(e)}
- -
{escape(traceback_message)}
- """), messages.ERROR - ) - else: self.message_user( request, f"Error For {id}: {escape(e)}", messages.ERROR) + #NOT sure if there is a clean way to get the model + #object_change_url = reverse( + # f'admin:{self._meta.model_name}_{self._meta.app_label}_change', + # kwargs={'object_id': self.pk} + #) + + self.message_user( + request, + loader.get_template("asyncron/admin-gather-error-message.html").render({ + "id": id, "e": e, + "traceback_message": traceback_message + }), + messages.ERROR + ) if failed == 0: self.message_user( request, f"All {len(results)} Succeeded!", messages.SUCCESS ) elif failed <= fails_to_show: diff --git a/asyncron/templates/asyncron/admin-gather-error-message.html b/asyncron/templates/asyncron/admin-gather-error-message.html new file mode 100644 index 0000000..8b26bdd --- /dev/null +++ b/asyncron/templates/asyncron/admin-gather-error-message.html @@ -0,0 +1,31 @@ +{% autoescape on %} + Error For Object {{ id }}: + {% if traceback_message %} + +
{{ e }}
+ +
{{ traceback_message }}
+ {% endif %} +{% endautoescape %} diff --git a/asyncron/templates/asyncron/codearea-widget.html b/asyncron/templates/asyncron/codearea-widget.html new file mode 100644 index 0000000..6c1f0fa --- /dev/null +++ b/asyncron/templates/asyncron/codearea-widget.html @@ -0,0 +1,56 @@ +{% load static %} + + + + +
+ {{ textarea }} +
{{ value }}
+
+ + +{{ hljs_config | json_script:"hlsj-config" }} + diff --git a/asyncron/widgets.py b/asyncron/widgets.py new file mode 100644 index 0000000..3063a45 --- /dev/null +++ b/asyncron/widgets.py @@ -0,0 +1,22 @@ + +from django.template import loader +from django.forms import Textarea + + +class Codearea( Textarea ): + + def __init__( self, *args, language = "auto", **kwargs ): + self.language = language + super().__init__( *args, **kwargs ) + + def render( self, name, value, attrs = None, renderer = None ): + print( self ) + print(f"RENDERING: {name=} {value=} {attrs=} {renderer=}") + return loader.get_template("asyncron/codearea-widget.html").render({ + "textarea": super().render( name, value, attrs, renderer ), + "value": value, + "target": name, + "hljs_config": { + "language": self.language + } + })