Hi Carlton,
Thanks for your response! If it’s OK can we carry on a bit of a detailed conversation here, the salient points can then be added to the ticket?
Thank you for pointing me in the direction of the tests, this was very helpful. I also appreciated your insight in that if a field has required
elements then it should defer to the sub-fields, this seems a logical approach.
I found test_multivalue_optional_subfields. This test is for the scenarios we are looking at. This also led me to the original ticket (#15511) that introduced this functionality. It shows that required_all_fields
was introduced as a flag to allow sub-widgets to be optional whilst retaining backwards compatibility.
The docs also have something to say on required_all_fields
.
When set to False, the Field.required attribute can be set to False for individual fields to make them optional. If no value is supplied for a required field, an incomplete validation error will be raised.
My view is that the current implementation doesn’t quite work in this way as an empty response is valid; I think the docs would indicate it should raise an incomplete
error.
Given this, I think there are two potential solutions for the clean
method.
Option 1: required = false
& require_all_fields=false
& null response = incomplete error
This option would only change the validation outcome of a small set of test cases. Specifically those where a valid input is currently being returned for a null response despite there being required sub-fields. These tests are line 3034-3036 and I would expect these to raise a ValidationError
.
The benefit of this option is it’s a fairly small change from the current behaviour and simply aligns to the description in the documentation.
Option 2: required = false
assumes field can be empty in it’s entity; required=true
defers to sub-fields
In this solution I propose we remove require_all_fields
as the logic would flow down to individual sub-fields when required=true
on MVF. Whilst this option seems a cleaner implementation this would be a more fundamental change and causes backwards compatibility issues.
Therefore given where the project is at, is this a solution that we should proceed with? If so I’d appreciate some guidance on how to approach this. In my head we could introduce ‘new’ way and slowly deprecate the ‘old’ way?
HTML5 Required
attribute
In the ticket I also commented about the HTML5 required
attribute. There is a fairly easy solution here in that it can be overridden by passing the required
setting into the attrs
dict for each widget e.g.
widgets = [TextInput(attrs={'required': True}), TextInput(attrs={'required': False})]
Having looked at the tests I can’t see any coverage of ‘required’ attributes for multivalue field.
We therefore have the option of trying to improve the default required
settings by deferring to the subwidgets. In BoundField.build_widget_attrs()
we could check if the field is a MVF, and add the required status based on each subfield rather than MVF itself. Note: Whilst logic above makes sense to me, I’ve not yet given any thought to how this would be implemented.
Questions
Assuming the above makes sense there are a couple of questions which will help me progress this. 
-
Do you have a preference in how we should improve the clean
method, either one of my options above or something I’ve not thought of?
-
Do you have a view on if investigating the build_widget_attrs
logic to try and respect the required status of individual widgets is worthwhile?
Thanks
David
p.s. bit of feedback - you can post 2 links in a reply. I had to chop a fair few out to comply with this rule.