1

Problem Statement

I have a Django model containing a JSONField among other fields:

class MetaData(models.Model):
     main = models.ForeignKey()
     name = models.CharField()
     dict_field = models.JSONField()

Where dict_field is a "data dump" for any remaining metadata that i don't want to include as a standalone field.

Although it's a data "dump", I still want it to have basic type-validation. How can I validate the inputs of this JSONField such that it only accepts a pre-defined list of keys and their associated types, as follows:

"key1": bool
"key2": int
"key3": Optional[int]

Does django have functionality built in for this type of problem? If not, what other solutions can you recommend? (pydantic, etc.)

Joseppy
  • 13
  • 4

1 Answers1

0

You can write a validator for that:

from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible


@deconstructible
class BasicJsonValidator:
    def __init__(self, types):
        self.types = types

    def __call__(self, mydict):
        if not isintance(mydict, dict):
            raise ValidationError('Value must be a dictionary.')
        for key, value in mydict.items():
            if key not in self.types:
                raise ValidationError(f'key {key} should not be present')
            if not isinstance(value, self.types[key]):
                raise ValidationError(
                    f'for {key}, {value} should be a {self.types[key]}'
                )

Then you can use a validator with:

class MetaData(models.Model):
    main = models.ForeignKey()
    name = models.CharField()
    dict_field = models.JSONField(
        validators=[
            BasicJsonValidator({'key1': bool, 'key2': int, 'key3': Optional[int]})
        ]
    )
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555