Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/jsonschema model #2

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Welcome to django-json-schema's documentation!

|python-versions| |django-versions| |pypi-version|

<One liner describing the project>
A reusable Django app to store json schemas.
Floris272 marked this conversation as resolved.
Show resolved Hide resolved

.. contents::

Expand All @@ -21,8 +21,10 @@ Welcome to django-json-schema's documentation!
Features
========

* ...
* ...
* JsonSchemaModel consisting of
- name CharField
- schema JsonField
- validate(json) method to validate JSON against the schema.

Installation
============
Expand All @@ -32,6 +34,7 @@ Requirements

* Python 3.10 or above
* Django 4.2 or newer
* A database supporting django.db.models.JSONField


Install
Expand All @@ -45,7 +48,19 @@ Install
Usage
=====

<document or refer to docs>
.. code-block:: python

from django-json-schema.models import JsonSchema
Floris272 marked this conversation as resolved.
Show resolved Hide resolved

class ProductType(models.Model):
schema = models.ForeignKey(JsonSchema, on_delete=models.PROTECT)

class Product(models.Model):
json = models.JsonField()
type = models.ForeignKey(ProductType, on_delete=models.CASCADE)

def clean(self):
self.type.schema.validate(self.json)

Local development
=================
Expand Down
8 changes: 8 additions & 0 deletions django_json_schema/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.contrib import admin

from .models import JsonSchema


@admin.register(JsonSchema)
class JsonSchemaAdmin(admin.ModelAdmin):
search_fields = ["name"]
43 changes: 43 additions & 0 deletions django_json_schema/locale/nl/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-07 05:36-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: models.py:10
msgid "name"
msgstr "naam"

#: models.py:10
msgid "Name of the json schema."
msgstr "Naam van het json schema."

#: models.py:14
msgid "schema"
msgstr ""

#: models.py:14
msgid "The schema that can be validated against."
msgstr "Het schema waartegen gevalideerd kan worden."

#: models.py:18
msgid "Json schema"
msgstr ""

#: models.py:19
msgid "Json Schemas"
msgstr "Json Schema's"
45 changes: 45 additions & 0 deletions django_json_schema/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Generated by Django 4.2.17 on 2025-01-03 16:37

from django.db import migrations, models


class Migration(migrations.Migration):
initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="JsonSchema",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"name",
models.CharField(
help_text="Name of the json schema.",
max_length=200,
verbose_name="name",
),
),
(
"schema",
models.JSONField(
help_text="The schema that can be validated against.",
verbose_name="schema",
),
),
],
options={
"verbose_name": "Json schema",
"verbose_name_plural": "Json Schemas",
},
),
]
Empty file.
29 changes: 29 additions & 0 deletions django_json_schema/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _

from jsonschema import validate
from jsonschema.exceptions import ValidationError as JsonSchemaValidationError


class JsonSchema(models.Model):
name = models.CharField(
_("name"), help_text=_("Name of the json schema."), max_length=200
)

schema = models.JSONField(
_("schema"), help_text=_("The schema that can be validated against.")
)

class Meta:
verbose_name = _("Json schema")
verbose_name_plural = _("Json Schemas")

def __str__(self):
return self.name

def validate(self, json: dict) -> None:
try:
validate(json, self.schema)
except JsonSchemaValidationError as e:
raise ValidationError(e.message)
8 changes: 5 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ Welcome to django-json-schema's documentation!
..
|docs| |python-versions| |django-versions| |pypi-version|

<One liner describing the project>
A reusable Django app to store json schemas.

Features
========

* ...
* ...
* JsonSchemaModel consisting of
- name CharField
- schema JsonField
- validate(json) method to validate JSON against the schema.

.. toctree::
:maxdepth: 2
Expand Down
15 changes: 14 additions & 1 deletion docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,17 @@ Install from PyPI with pip:
Usage
=====

<document how to use the app here>
.. code-block:: python

from django.db import models
from django-json-schema.models import JsonSchema

class ProductType(models.Model):
schema = models.ForeignKey(JsonSchema, on_delete=models.PROTECT)

class Product(models.Model):
json = models.JsonField()
type = models.ForeignKey(ProductType, on_delete=models.CASCADE)

def clean(self):
self.type.schema.validate(self.json)
10 changes: 10 additions & 0 deletions manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
os.environ["DJANGO_SETTINGS_MODULE"] = "testapp.settings"

from django.core.management import execute_from_command_line

execute_from_command_line(sys.argv)
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ classifiers = [
]
requires-python = ">=3.10"
dependencies = [
"django>=4.2"
"django>=4.2",
"jsonschema>=4.23",
]

[project.urls]
Expand Down
33 changes: 33 additions & 0 deletions tests/test_json_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from django.core.exceptions import ValidationError
from django.test import TestCase

from django_json_schema.models import JsonSchema


class TestJsonSchema(TestCase):
def setUp(self):
self.schema = JsonSchema.objects.create(
name="schema",
schema={
"type": "object",
"properties": {
"price": {"type": "number"},
"name": {"type": "string"},
},
"required": ["price", "name"],
},
)

def test_valid_json(self):
self.schema.validate(
{
"price": 10,
"name": "test",
}
)

def test_invalid_json(self):
with self.assertRaisesMessage(
ValidationError, "'price' is a required property"
):
self.schema.validate({"name": "Eggs"})
Loading