Git Product home page Git Product logo

django-jsonform's Introduction

django-jsonform icon

A user-friendly JSON editing form for django admin.

DocumentationPlaygroundPyPI

Features

  • File uploads
  • Postgres ArrayField
  • Many inputs and field types
  • UI matches with Django admin's
  • Recursion (nesting with self references)
  • Validation

Screenshots

Here's a screenshot of items being added to a shopping list (JSON array) dynamically:

django-jsonform screenshot

Install

Install via pip:

$ pip install django-jsonform

Edit your settings.py file:

# settings.py

INSTALLED_APPS = [
    # ...
    'django_jsonform'
]

Upgrading notes

When upgrading from an older version of this library, please ensure that your browser is loading the latest static JavaScript files that come with this library.

  • In the development environment, clear the browser cache.
  • In the production environment, you must run the collectstatic command to update the static files.

Documentation

Quickstart and usage docs can be found at http://django-jsonform.rtfd.io.

Contributing

  • The JavaScript code is written in React and it lives in another repo: https://github.com/bhch/react-json-form.
    The JS code lacks proper documentation or comments, so before contributing, maybe open an issue and I can help you out.
  • For everything else (related to Django or widget's css), contribute directly to this repo.

License

BSD-3-Clause

django-jsonform's People

Contributors

andres-holvi avatar bhch avatar kviktor avatar martingouy avatar mick88 avatar nlsfnr avatar nullcode avatar powdahound avatar rglsk avatar ryanhiebert avatar trumpet2012 avatar willnilges avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

django-jsonform's Issues

Provide a template filter for converting iso datetime string to a datetime object

datetime is stored as an ISO string in the json object. Since it's a string, Django's date filter doesn't work on it in the templates.

It would be better if there were a template filter which would convert the string datetime to a Python's actual datetime object.

Perhaps something like these:

  • parse_datetime: for parsing datetime and date string
  • parse_time: for parsing time string

Add allOf/anyOf/oneOf concept

One of the very useful features in JSON Schemas is the option to have multiple options via allOf/anyOf/oneOf for the same key/set of keys when nesting. For our project github.com/cividi/spatial-data-package-platform this would solve a major hurdle for fully embracing django-jsonform as an elegant solution for tenant defined forms. Would be awesome to know if this is at all thinkable as a future addition. Thanks so much for your efforts.

Docs not clear on what needs to be done in admin.

It took me a while to figure out that I had to register the model like this in the admin.py file in order for it to show up correctly:

class ModelNameForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["field_name"].widget.instance = self.instance

    class Meta:
        model = ModelName
        exclude = []


class ModelNameAdmin(admin.ModelAdmin):
    form = ModelNameForm


admin.site.register(ModelName, ModelNameAdmin)

It was hard to find that part in the documentaiton and when I found it, the documentation was incomplete.

Awesome app, but psycopg2 has to be installed in order to work

Hi there,

This is something I was looking for a while.

This app has huge potential, thank you for creating it!

There was a few issue though I came across immediately when I tried.

  1. I had to install psycopg2 in order to able to use django_jsonform.models.fields.JSONField. I got the ‘No module named 'psycopg2'’ error when I tried to run makemigrations.

  2. Django’s built in collapsable fieldsets stopped working after this field type has been added to my model. Any custom fieldset classes are splitted up by spaces when it’s rendered when JSONField is present.

I could fix this issue by wrapping my custom classes into an additional list.

'classes': (['collapse’]) # instead of 'classes': ('collapse')

https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets

  1. Some enhancment tip: it would be neat to be able to separate larger fieldset groups without having to add more JSONField to my model.

Otherwise very good job. I’ll use this app on my website since the next update.

Thanks!

Choice field returning empty values

Hi @bhch

I have a form displaying the following address information. The state choices is filled based on country through jQuery.
The problem is, the address object in DB is empty i.e. {country:"",state:""}.

Am i missing something?

django version: 3.2
using jazzmin for the dashboard UI

ADDRESS={
"type": "dict",
"keys": {
"country": {
"type": "string",
'choices': ['India','China',....]
},
"state": {
"type": "string",
'choices': []
}
}
}

//models.js
address = JSONField(schema=ADDRESS)

Defaults not working as expected for size-limited array

Creating a form using this schema:

DEFAULT_PARAMETERS_SCHEMA = {
    "type": "object",
    "properties": {
        "max_weekday_characteristics": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {},
                "additionalProperties": {
                    "type": "integer",
                    "helpText": "Key is a tag-name. Value is the maximum for that tag",
                },
            },
            "minItems": 7,
            "maxItems": 7,
            "default": [{}, {}, {}, {}, {}, {}, {}],
            "title": "Maximum Characteristics per Weekday",
        },
    },
}

has unexpected behaviour. I would expect that the default form would look like this:
Screenshot from 2022-08-12 12-24-41
but it instead defaults to being an empty list. I think this is a bug, but please advise.

make it simpler to access schema through foreign key relation

Hey,
thanks for this library. I have a use-case that I believe is fairly normal as I've had to do the same thing in multiple different situations/projects. Using your library I've had to do some workarounds to get there.

The setup is this: I have to store annual surveys in the database. The surveys are always have a few fields that always need to be included (name, date, etc.) and other fields that change every year. So I create two models in the database:

class SurveyType(models.Model):
    name = models.CharField(max_length=255)
    schema = models.JSONField(default=dict)

    def __str__(self):
        return self.name

class SurveyEntry(models.Model):
    participant_name = models.Charfield(max_length=255)
    date = models.DateField()
    survey_type = models.ForeignKey(
        SurveyType,
        on_delete=models.CASCADE,
    )
    survey_data = jsonformJSONField(schema=lambda instance: instance.survey_type.schema)
    

This looks good, but it won't work as initially when entering a new SurveyEntry, no survey_type has been defined. It would be good if there was a way to handle that. The work around I found was to do this to SurveyEntry:

class SurveyEntry(models.Model):
    participant_name = models.Charfield(max_length=255)
    date = models.DateField()
    survey_type = models.ForeignKey(
        SurveyType,
        on_delete=models.CASCADE,
    )
    survey_data = jsonformJSONField(
        schema=lambda instance=None: instance.survey_type.schema
        if instance and hasattr(instance, "survey_type")
        else {"type": "object", "properties": {}},
        null=True,
        blank=True,
    )
    def save(self, *args, **kwargs):
        if not bool(self.survey_data):
            # This was likely based on the default schema. Remove again.
            self.survey_data = None
        return super().save(*args, **kwargs)

Improve Django version check

The current check works only for Django 3.xxx:

django.VERSION[0] >= 3 and django.VERSION[1] >= 1:

Recently a new Django version was released 4.0..., with the old check the package is not working because of: django.VERSION[1] >= 1

[Suggestion] Foreign key field

Hello! Thanks for sharing awesome library!

I came up with idea of extending the library to support foreign key id property field and select id using django's default autocomplete_field UI.

For example,
json schema would be like

{
        '$schema': 'http://json-schema.org/schema#',
        'type': 'array',
        'items': {
            'type': 'object',
            'required': [
                "model_id", "field"
            ],
            'properties': {
                'model_id': { -> foreign key id, maybe type should be `ExampleModel` or something else.
                    'title': 'entity',
                    'type': 'number',
                },
                'field': {
                    'title': 'field',
                    'type': 'string',
                }
            }
        }
    }

where there exists django model named ExampleModel.

class ExampleModel(models.Model):
    entity_field = models.CharField(max_length=32)

This feature might empower the functionalities of your cool library!

Thanks.

Add an Errors page in the docs

There are some searches in the docs related to the JS errors (when schema and data mismatch, etc.)

Add a page in the docs to explain the errors.

editor.html template is missing

I installed version 2.1.0 of the lib in my project and followed the quickstart tutorial, but I am now getting an error in the page where the field is supposed to render - template "django_jsonform/editor.html" does not exist. I checked that there's no "templates" directory in the locally installed django_jsonform package. The only folders are models and forms and the template is being referenced in JSONFormWidget.

error with whitenoise

with whitenoise environment
manage.py collectstatic

after this command, error pops up.

whitenoise.storage.MissingFileError: The file 'django_jsonform/local/react-json-form.js.map' could not be found with <whitenoise.storage.CompressedManifestStaticFilesStorage object at 0x112204fd0>.

The JS file 'django_jsonform/local/react-json-form.js' references a file which could not be found:
  django_jsonform/local/react-json-form.js.map

thanks in advance.

multiselect not work

django-jsonform version: 2.10.1
django version: 3.2.14

I have this model field which is an array imported from django_jsonform.models.fields, I would like it to be shown in the admin panel as a multiselector of another model, a kind of Foreign Key where, however, I go to save only the ids of the selected models.

image

In my admin form I first tried to do a test with the choices you see here, but i can't select anything.

PS. radio widget works

image
ezgif com-gif-maker

Another question:
image

another question, how do I increase the size of the input?

widget.attrs = {'style': 'width: 275px;'}
it does not work

Allow schema to be a callable

This would allow us to dynamically return the choices such as objects from the database.

This would also allow us to return a schema based on user permissions.

Django Model not respecting the default if it is 0

weekend_days = JSONField(schema={
"type": "dict",
"keys": {
"monday": {
"type": "number",
"default": 0
},
"tuesday": {
"type": "number",
"default": 0
}
}
} )

I use Django 4.1, Django json form 2.10.1. So, when I run the above as a model field in Django, instead of setting 0 as default value for keys Monday, Tuesday, the Django-jsonform sets Null as the value which is not expected

Try to add through inline doesnt save the json

If I try to add a new related object that has a jsonform through an inline it doesn't save the options.
If I edit it works as expected.

models.py:

from django.db import models

from django_jsonform.models.fields import JSONField


PREF_SCHEMA = {
    "type": "dict",
    "keys": {
        "periodTime": {
            "title": "Time of day",
            "type": "dict",
            "keys": {
                "morning": {
                    "type": "boolean",
                    "title": "Morning",
                },
                "afternoon": {
                    "type": "boolean",
                    "title": "Afternoon",
                },
                "evening": {
                    "type": "boolean",
                    "title": "Evening",
                },
            },
        },
    },
}


class MyModel(models.Model):
    name = models.CharField(max_length=50, null=True, blank=True)

class MyRelatedModel(models.Model):
    pref = JSONField(schema=PREF_SCHEMA)
    mymodel = models.ForeignKey(MyModel, on_delete=models.CASCADE)

admin.py:

from django.contrib import admin
from django import forms

from .models import MyModel
from .models import MyRelatedModel



class MyRelatedModelForm(forms.ModelForm):
    class Meta:
        model = MyRelatedModel
        fields = ("pref",)



class MyRelatedModelInline(admin.TabularInline):
    model = MyRelatedModel
    form = MyRelatedModelForm
    extra = 0
    can_delete = True



@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    inlines = (MyRelatedModelInline,)


@admin.register(MyRelatedModel)
class MyRelatedModelAdmin(admin.ModelAdmin):
    pass

Here is a full project with that issue happening:

proj.zip

Support lazy-translatable title strings

Currently trying to use a translated lazy string as a "title", produces an error in v2.6.0:
TypeError: Object of type __proxy__ is not JSON serializable

Example schema:

    from django.utils.translation import gettext_lazy as _
    {
        'type': 'object',
        'keys': {
            'show': {
                'type': 'boolean',
                'title': _('Show')
            },
        },
    }

Editing an extendable dict's key makes it disappear

Steps to reproduce:

  1. Add a new key in an extendable dict
  2. Edit that key
  3. Key disappears

This happens in nested dicts. In fact, the disappeared key is added to the outer dict if outer dict also supports additional keys.

2 array field in one row (fieldset)

I didn't pass any custom css or attr style to widget to make it format, I just formatted the 2 array fields on a single line using fieldsets.

image

image
image

A list of objects automatically add an item even if all of the fields are empty

        schema={
            'type': 'array',
            'items': {
                'type': 'dict',
                'keys': {
                    'foo': {
                        'type': 'string',
                    },
                    'bar': {
                        'type': 'string',
                    },
                },
            },
        },

if you edit an instance that has [] in database, even if you don't touch any of the fields, it automatically stores

[{"foo": "", "bar": ""}]

While I understand that's how django manages empty string fields, setting them to an empty string instead of null, it doesn't make sense for it to happen in cases like this. It's causing us problems because then our frontend/api tries to return this stuff and it shows an empty item.

I'm not sure how to handle this case, but here's three suggestions:

  • If min_items is 0, don't show an empty item by default, but if a user clicks on add item and doesn't add anything the issue still happens, which is not really the expected behavior.
  • A new option for dicts to only be stored if any of the values is not null (nested objects are a problem)
  • Let the user handle it by extending the field

Dropdown not appearing in admin page when setting a default value in model.

Hi,

I've been using this package due to the very friendly UI on the admin page + it substitutes the ArrayField which would crash all my sqlite3 unit tests (my actual DB is PostgreSQL).

However, I noticed that once I add a 'default=dict', or any callable for that matter, then the dropdown no longer works on django admin: clicking the '+' does nothing.

Is this a bug? If not, could you provide me an example of how to specify a default value in my model for the JSONField?

Thanks!

Default not being respected

weekend_days = JSONField( blank=True, help_text="Days of the week which are considered weekend days (format is DAY_NAME:1, eg. sunday:1)", schema={ "type": "dict", "keys": { "monday": {"type": "number", "default": 1}, "tuesday": {"type": "number", "default": 0}, "wednesday": {"type": "number", "default": 0}, "thursday": {"type": "number", "default": 0}, "friday": {"type": "number", "default": 0}, "saturday": {"type": "number", "default": 1}, "sunday": {"type": "number", "default": 1}, }, }, )

In the above scenario, the weekend_days when complied sets to null, instead of 0, so when I query I get
` {
            "monday": 1,
            "tuesday": null,
            "wednesday": null,
            "thursday": null,
            "friday": null,
            "saturday":1,
            "sunday":1,
   }`

I use Django 4.1, postgres 13, django-jsonform 2.10.1

Allow for dict keys to only be set if value is not null

We have a field that is like this:

    action_timestamps = JSONField(
        default=dict,
        schema={
            'type': 'object',
            'keys': {
                'timestamp_1': {
                    'type': 'string',
                },
                'timestamp_2': {
                    'type': 'string',
                },
            }
        },
    )

Outside of the admin, we set the timestamps only when they are needed.
So for example this could be a valid value for us:

{
    "timestamp_1": "2018-11-19 12:10:02.353829"
}

However, once you edit the model from the admin, that value is set to:

{
    "timestamp_1": "2018-11-19 12:10:02.353829", 
    "timestamp_2": ""
}

Would it be possible to add a keyword to the schema key that makes so the key isn't stored unless it has a non falsy value?

Allow passing the file upload handler alongwith schema

Currently only one handler can be specified in the settings. This pattern poses problems if a third party app also has a handler.

Passing an upload handler function to the JSONField or the widget will allow different apps or models to use different upload handler functions.

Support datetime format(s) for strings

A basic feature would be to add the format to the string type returned by datetime.datetime.isoformat()

This would require a datetime picker in the admin.

A more advanced way to do it would be to allow custom datetime formats, like "YYYY-MM-DD HH:MM", but this is more complicated and with the basic feature anybody could extend the field and format the datetime into their desired format

I love the package, btw!.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.