-
-
Notifications
You must be signed in to change notification settings - Fork 34
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
Callable schemas and initial values #85
Comments
Hi, I think I kind of understand what you're proposing. But if you could also provide a minimal example of the model and your callable schema function, it will be a bit clearer to me. |
Hello, def schema_getter(some_property):
# .... <fetches schema based on value of `some_property`>
# Model
class MyModel(models.Model):
some_property = models.CharField(max_length=128)
def callable_config_schema(model_instance=None):
# Here it would be great to be able to know what the initial value of
# `some_property` is, as the model instance hasn't been instantiated yet
# for CreateView
if model_instance: return schema_getter(model_instance.some_property)
some_json = JSONField(schema=callable_config_schema)
# Form
class MyModelForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# This is my hack to make sure the schema is correctly selected
if kwargs.get("initial", {}).get("some_property"):
self.fields["some_json"].widget.schema = self.fields[
"some_json"
].widget.schema(MyModel(integration_id=kwargs["initial"]["some_property"]))
# manually set the current instance on the widget
# see https://django-jsonform.readthedocs.io/en/latest/fields-and-widgets.html#accessing-model-instance-in-callable-schema
self.fields["some_json"].widget.instance = self.instance
class Meta:
model = MyModel
fields = "__all__"
# View
class MyCreateView(CreateView):
model = MyModel
form_class = MyModelForm
def get_initial(self):
# self.kwargs contains parameters from the url
return {'some_property': self.kwargs['some_property']} In urls.py: urlpatterns = [
path(
"some/path/<some_property>/",
views.MyCreateView.as_view()
),
.... |
Okay, everything is clear now. I will provide a way to pass extra arguments to the callable in the next release. Probably introduce a new attribute called # declare extra arguments to pass to the callable schema
self.fields['some_json'].widget.schema_kwargs = {'key': value, ...} Meanwhile, let me suggest a simpler hack for your use case. The widget doesn't care what the value of the # form
class MyModelForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["some_json"].widget.instance = {
'instance': self.instance,
'some_property': kwargs['initial']['some_property']
}
# callable
def callable_config_schema(data):
"""
data is a dict containing these keys:
- instance: instance of the model
- some_property: value of some_property field
""""
if data['instance'] is not None:
# model instance is present
...
else:
# no instance found, so use data['some_property'] value
... |
Good idea - thanks! |
Hello,
It seems that callable schemas don't have knowledge of initial values (e.g. using a
CreateView
), as the schema callable only receives the model instance as parameter, which is not initialised.For example, using a model
MyModel
having aJSONField
with a callable schema based on the model'ssome_property
attribute, and using this viewthe callable schema will not be able to return a schema based on the initial
some_property
value.Wouldn't it make sense to pass the initial values to the callable? They are passed to the
kwargs
ofMyModelForm
.The text was updated successfully, but these errors were encountered: