Closed ErikKoinberg closed 5 months ago
I solved this using widget: hidden
I think this should be re-opened as the original use-case should still be supported by the library without a workaround.
In my case I'm using django-pydantic-field
and I have a field like this:
my_mapping: Dict[str, str] = Field(default={})
that has no properties/keys pre-defined.
I need the widget working and visible to allow users to edit this value and add str: str
mapping entries.
I think django-jsonform
should support objects with no properties
or keys
defined as long as they have additionalProperties
set.
I've also noticed that if the object is already populated with some user-provided additional parameters that aren't defined in properties
/keys
, they don't show up in the UI at all. This makes it hard to implement these forms to edit Dict[str, str]
because entries "disappear" after the user hits save and refreshes.
Related issue: https://github.com/surenkov/django-pydantic-field/issues/64
As a workaround I've monkey-patched JSONFormWidget
to achieve the desired behavior:
from django.contrib import admin
from django_jsonform.widgets import JSONFormWidget
from django_pydantic_field.v2.fields import PydanticSchemaField
from project.models import Dependency
def patch_schema_for_jsonform(schema):
"""recursively patch a schema dictionary in-place to fix any missing properties/keys on objects"""
# base case: schema is type: "object" with no properties/keys
if schema.get('type') == 'object' and not ('properties' in schema or 'keys' in schema):
if 'default' in schema and isinstance(schema['default'], dict):
schema['properties'] = {
key: {"type": "string", "default": value}
for key, value in schema['default'].items()
}
# setting the actual value as a default on a hardcoded property is still not ideal as it doesn't allow the user to remove this entry from the UI, but at least it shows up
else:
schema['properties'] = {}
# recursive case: iterate through all values and process any sub-objects
for key, value in schema.items():
if isinstance(value, dict):
patch_schema_for_jsonform(value)
class PatchedJSONFormWidget(JSONFormWidget):
def get_schema(self):
self.schema = super().get_schema()
patch_schema_for_jsonform(self.schema)
return self.schema
class DependencyAdmin(admin.ModelAdmin):
formfield_overrides = {PydanticSchemaField: {"widget": PatchedJSONFormWidget}}
admin.site.register(Dependency, DependencyAdmin)
I have a usage case in which I need the user to define a set of custom properties. I do not want nor need any normal properties. Adding any would just be unnecessary and obtrusive. Is it possible to make an object with empty "properties" or at least hide a fields inside of that for the end user, as a possible fix?