About Indented JSON Fields in Administration

By default, JSON fields in administration are not indented and are challenging to analyze. To indent them, create a custom model form as such:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# forms.py
import json
from django import forms

class IndentedJSONEncoder(json.JSONEncoder):
    def __init__(self, *args, indent, **kwargs):
        super().__init__(*args, indent=2, **kwargs)

class ModelFormWithJSONFields(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            if isinstance(field, forms.JSONField):
                model_field = self._meta.model._meta.get_field(field_name)
                self.fields[field_name] = forms.JSONField(
                    label=model_field.verbose_name,
                    encoder=IndentedJSONEncoder,
                    required=not model_field.blank,
                    widget=forms.Textarea(attrs={"class": "vLargeTextField"}),
                )

Then use the form in the model admins and inlines, so:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# admin.py
from django.contrib import admin
from .forms import ModelFormWithJSONFields

class LessonInline(admin.StackedInline):
    model = Lesson
    form = ModelFormWithJSONFields
    extra = 0

@admin.register(Section)
class SectionAdmin(admin.ModelAdmin):
    form = ModelFormWithJSONFields
    list_display = ["__str__"]
    inlines = [LessonInline]

Tips and Tricks Programming User Experience Django 4.2 Django 3.2 Django 2.2 Python 3