Skip to content

Instantly share code, notes, and snippets.

@mo-mughrabi
Created June 2, 2020 10:59
Show Gist options
  • Save mo-mughrabi/e874714a4180e76614f638e7c23b5896 to your computer and use it in GitHub Desktop.
Save mo-mughrabi/e874714a4180e76614f638e7c23b5896 to your computer and use it in GitHub Desktop.
A base django model for reformatted JSONFields to be disabled in admin
# This is definitely not the best approach and preferably if we can use django admin base class would be better.
# base model
import json
from django.contrib.postgres.fields import JSONField
from django.db import models
from django.utils.safestring import mark_safe
from pygments import highlight
from pygments.formatters.html import HtmlFormatter
from pygments.lexers.data import JsonLexer
class ModelJSONIndentedFields(models.Model):
""" ModelJSONIndentedFields
Allows for configuring class meta to create a property of the field
for displaying json indented format
"""
class Meta:
abstract = True
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self._meta.get_fields():
if isinstance(field, JSONField):
# TODO: Add short description to attr
setattr(
self,
f"{field.name}_formatted",
self.payload_formatted(field.name)
# TODO: Use property to invoke formatter on getattr
# property(lambda x: self.payload_formatted(field.name))
)
def payload_formatted(self, field):
data = json.dumps(getattr(self, field), indent=2)
formatter = HtmlFormatter(style="colorful")
response = highlight(data, JsonLexer(), formatter)
style = "<style>" + formatter.get_style_defs() + "</style><br/>"
return mark_safe(style + response)
# unit testing it
import pytest
from django.contrib.postgres.fields import JSONField
from django.db import models, connection
from lkl_core.utils.models import ModelJSONIndentedFields
@pytest.mark.django_db
def test_model_json_indent_fields():
class ExampleClassJson(ModelJSONIndentedFields):
field_a = JSONField()
field_b = models.CharField(max_length=100)
class Meta:
app_label = "example"
db_table = "test_container"
def setup_models(*args):
with connection.schema_editor(atomic=True) as schema_editor:
for model in args:
schema_editor.create_model(model)
setup_models(ExampleClassJson)
a = ExampleClassJson(field_a={"example": "example"})
assert hasattr(a, "field_a_formatted")
assert not hasattr(a, "field_b_formatted")
assert "example" in getattr(a, "field_a_formatted")
assert "<style>" in getattr(a, "field_a_formatted")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment