Skip to content

Commit

Permalink
ModelRelatedField can have string pk and this will not work with the …
Browse files Browse the repository at this point in the history
…default datatype 'json' used in entityfilter widget. (backport 2.4)
  • Loading branch information
joehybird committed Jan 10, 2024
1 parent 9a5a042 commit 52e6a7a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
- The 'DynamicSelect' widget now accepts 'avoid_empty' constructor argument : when true the 'data-no-empty' attribute is enabled on client side.
- Keep the actual behaviour of 'DynamicSelect' within the ChainedSelect widget definitions:
- Add avoid_empty=True to all DynamicSelect having a child dependency.
# In 'creme_core.forms.entity_filter':
- ModelRelatedField can have string pk and this will not work with the default datatype 'json' used in entityfilter widget.
# In Javascript :
- 'creme.form.Select2' now supports the lazy loading of selections :
Useful in entity filter polymorphic inputs that do not know the selected options beforehand.
Expand Down
9 changes: 7 additions & 2 deletions creme/creme_core/forms/entity_filter/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ def _build_valueinput(self, field_attrs):
EQUALS_OPS = f'{operators.EQUALS}|{operators.EQUALS_NOT}'
add_input = pinput.add_input

# json datatype will consider pk strings as an invalid value and replaced
# by "null"
enum_field_attrs = {**field_attrs, 'datatype': 'string'}

def is_enumerable_field(field):
return isinstance(field, ModelRelatedField) and (
not issubclass(field.remote_field.model, (CremeEntity, get_user_model()))
Expand All @@ -171,13 +175,13 @@ def is_choices_field(field):
if is_enumerable_field(field):
add_input(
f'^enum(__null)?.({EQUALS_OPS}).{name}$',
widget=FieldEnumerableSelect, attrs=field_attrs,
widget=FieldEnumerableSelect, attrs=enum_field_attrs,
field=field,
)
elif is_choices_field(field):
add_input(
f'^choices(__null)?.({EQUALS_OPS}).{name}$',
widget=DynamicSelectMultiple, attrs=field_attrs,
widget=DynamicSelectMultiple, attrs=enum_field_attrs,
options=field.choices,
)

Expand Down Expand Up @@ -306,6 +310,7 @@ def field_choicetype(field):
return 'string'

def get_context(self, name, value, attrs):
# TODO : the default datatype should be "json" only for JSONField.
field_attrs = {'auto': False, 'datatype': 'json'}

if self.autocomplete:
Expand Down
10 changes: 9 additions & 1 deletion creme/creme_core/static/creme_core/js/widgets/dselect.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@

creme.widget = creme.widget || {};

function datatypeConverter(datatype) {
if (datatype === 'json') {
return function(data) {
return creme.widget.cleanval(data, null);
};
}
}

creme.widget.DynamicSelect = creme.widget.declare('ui-creme-dselect', {
options: {
backend: undefined, // new creme.ajax.Backend({dataType:'json', sync:true}),
Expand Down Expand Up @@ -65,7 +73,7 @@ creme.widget.DynamicSelect = creme.widget.declare('ui-creme-dselect', {

_initModel: function(element, options) {
var self = this;
var converter = this._converter = options.datatype === 'json' ? function(data) { return creme.widget.cleanval(data, null); } : undefined;
var converter = this._converter = datatypeConverter(options.datatype);
var initial = creme.model.ChoiceGroupRenderer.parse(element, converter);

this._model = new creme.model.AjaxArray(this._backend, initial);
Expand Down

0 comments on commit 52e6a7a

Please sign in to comment.