目次
JSONFieldの値に日本語が入ってると文字化け
DjangoAdminの編集画面では、JSONFieldの値に日本語が入っていると文字化けして、unicodeになってしまいます。
そこで、以下のような形で、JSONField用にFormを作ってあげる必要があります。
import json from django.contrib.postgres.forms.jsonb import InvalidJSONInput, JSONField class ReadableJSONFormField(JSONField): def prepare_value(self, value): if isinstance(value, InvalidJSONInput): return value return json.dumps(value, ensure_ascii=False, indent=4)
ModelFormでFieldをoverrideする
使い方としては幾つかあります。まずはModelFormでモデルのFieldをoverrideする方法です。
上記で作成した、ReadableJSONFormFieldを使用してFieldを上書いてあげます。そうすることで、編集時も日本語が正しく表示されます。
from django import forms class ExampleForm(forms.ModelForm): samples = ReadableJSONFormField(required=False) class Meta: models = Examples fields = (samples,)
ModelAdminでFieldをoverrideする
続いては、ModelAdminでJSONField全てに対してformを上書きする方法です。
やり方は簡単で、JSONFieldのform_classにReadableJSONFormFieldを与えてあげるだけで、編集時も日本語が正しく表示されます。
from django.contrib import admin @admin.register(Examples) class ExampleAdmin(admin.ModelAdmin): formfield_overrides = { JSONField: {'form_class': ReadableJSONFormField}, }
ModelのJSONFieldのサブクラスを作成してformfield関数をoverrideする
最後にJSONFieldのサブクラスを作ってしまい、全モデルのJSONFieldで使うといった方法です。
モデルのJSONFieldのformfield関数でセットされているform_classを置き換えてあげます。そうすることで、モデルでJSONFieldを使う場合には、こちらのReadableJSONFieldを使えばAdmin側でも問題なく、日本語が表示されるようになります。
from django.contrib.postgres.fields import JSONField class ReadableJSONField(JSONField): def formfield(self, **kwargs): return super().formfield(**{ 'form_class': ReadableJSONFormField, **kwargs, })
色々なところで置き換えれることも分かり、勉強になりました。
どのレイヤーでformを書き換えてあげるかですが、モデルで使う用のサブクラスを一個作っておくと楽で良いんじゃないかなぁと思います。