til: django_pretty-print-json-admin.md
This data as json
| path | topic | title | url | body | html | shot | created | created_utc | updated | updated_utc | shot_hash | slug |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| django_pretty-print-json-admin.md | django | Pretty-printing all read-only JSON in the Django admin | https://github.com/simonw/til/blob/main/django/pretty-print-json-admin.md | I have a bunch of models with JSON fields that are marked as read-only in the Django admin - usually because they're recording the raw JSON that was imported from an API somewhere to create an object, for debugging purposes. Here's a pattern I found for pretty-printing ANY JSON value that is displayed in a read-only field in the admin. Create a template called `admin/change_form.html` and populate it with the following: ```html+django {% extends "admin/change_form.html" %} {% block admin_change_form_document_ready %} {{ block.super }} <script> Array.from(document.querySelectorAll('div.readonly')).forEach(div => { let data; try { data = JSON.parse(div.innerText); } catch { // Not valid JSON return; } div.style.whiteSpace = 'pre-wrap'; div.style.fontFamily = 'courier'; div.style.fontSize = '0.9em'; div.innerText = JSON.stringify(data, null, 2); }); </script> {% endblock %} ``` This JavaScript will execute on every Django change form page, scanning for `div.readonly`, checking to see if the div contains a valid JSON value and pretty-printing it using JavaScript if it does. It's a cheap hack and it works great. | <p>I have a bunch of models with JSON fields that are marked as read-only in the Django admin - usually because they're recording the raw JSON that was imported from an API somewhere to create an object, for debugging purposes.</p> <p>Here's a pattern I found for pretty-printing ANY JSON value that is displayed in a read-only field in the admin. Create a template called <code>admin/change_form.html</code> and populate it with the following:</p> <div class="highlight highlight-text-html-django"><pre><span class="pl-e">{%</span> <span class="pl-k">extends</span> <span class="pl-s">"admin/change_form.html"</span> <span class="pl-e">%}</span> <span class="pl-e">{%</span> <span class="pl-k">block</span> <span class="pl-s">admin_change_form_document_ready</span> <span class="pl-e">%}</span> {{ block.super }} <<span class="pl-ent">script</span>><span class="pl-s1"></span> <span class="pl-s1"><span class="pl-c1">Array</span>.<span class="pl-en">from</span>(<span class="pl-c1">document</span>.<span class="pl-c1">querySelectorAll</span>(<span class="pl-s"><span class="pl-pds">'</span>div.readonly<span class="pl-pds">'</span></span>)).<span class="pl-c1">forEach</span>(<span class="pl-smi">div</span> <span class="pl-k">=></span> {</span> <span class="pl-s1"> <span class="pl-k">let</span> data;</span> <span class="pl-s1"> <span class="pl-k">try</span> {</span> <span class="pl-s1"> data <span class="pl-k">=</span> <span class="pl-c1">JSON</span>.<span class="pl-c1">parse</span>(<span class="pl-smi">div</span>.<span class="pl-smi">innerText</span>);</span> <span class="pl-s1"> } <span class="pl-k">catch</span> {</span> <span class="pl-s1"> <span class="pl-c"><span class="pl-c">//</span> Not valid JSON</span></span> <span class="pl-s1"> <span class="pl-k">return</span>;</span> <span class="pl-s1"> }</span> <span class="pl-s1"> <span class="pl-smi">div</span>.<span class="pl-c1">style</span>.<span class="pl-c1">whiteSpace</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>pre-wrap<span class="pl-pds">'</span></span>;</span> <span class="pl-s1"> <span class="pl-smi">div</span>.<span class="pl-c1">style</span>.<span class="pl-c1">fontFamily</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>courier<span class="pl-pds">'</span></span>;</span> <span class="pl-s1"> <span class="pl-smi">div</span>.<span class="pl-c1">style</span>.<span class="pl-c1">fontSize</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>0.9em<span class="pl-pds">'</span></span>;</span> <span class="pl-s1"> <span class="pl-smi">div</span>.<span class="pl-smi">innerText</span> <span class="pl-k">=</span> <span class="pl-c1">JSON</span>.<span class="pl-c1">stringify</span>(data, <span class="pl-c1">null</span>, <span class="pl-c1">2</span>);</span> <span class="pl-s1">});</span> <span class="pl-s1"></span></<span class="pl-ent">script</span>> <span class="pl-e">{%</span> <span class="pl-k">endblock</span> <span class="pl-e">%}</span></pre></div> <p>This JavaScript will execute on every Django change form page, scanning for <code>div.readonly</code>, checking to see if the div contains a valid JSON value and pretty-printing it using JavaScript if it does.</p> <p>It's a cheap hack and it works great.</p> | <Binary: 73,754 bytes> | 2021-03-07T23:02:09-08:00 | 2021-03-08T07:02:09+00:00 | 2021-03-07T23:02:09-08:00 | 2021-03-08T07:02:09+00:00 | 1d4911dda034b51c8bcb108131578df4 | pretty-print-json-admin |