api: do not fully load the related table when filtering on an item(s) field (#74320) #101
|
@ -1381,6 +1381,59 @@ def test_api_list_formdata_item_filter(pub, local_user):
|
|||
assert len(resp.json) == result
|
||||
|
||||
|
||||
def test_api_list_formdata_item_filter_on_cards(pub, local_user, sql_queries):
|
||||
pub.role_class.wipe()
|
||||
role = pub.role_class(name='test')
|
||||
role.store()
|
||||
|
||||
local_user.roles = [role.id]
|
||||
local_user.store()
|
||||
|
||||
CardDef.wipe()
|
||||
carddef = CardDef()
|
||||
carddef.name = 'test'
|
||||
carddef.fields = [
|
||||
fields.StringField(id='0', label='String', type='string', varname='string'),
|
||||
]
|
||||
carddef.digest_templates = {'default': '{{ form_var_string }}'}
|
||||
carddef.store()
|
||||
|
||||
card_data_class = carddef.data_class()
|
||||
card_data_class.wipe()
|
||||
carddata = card_data_class()
|
||||
carddata.data = {'0': 'coin'}
|
||||
carddata.just_created()
|
||||
carddata.store()
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.workflow_roles = {'_receiver': role.id}
|
||||
formdef.fields = [
|
||||
fields.ItemField(
|
||||
id='0', label='Item', type='item', data_source={'type': 'carddef:test'}, varname='item'
|
||||
),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
data_class = formdef.data_class()
|
||||
data_class.wipe()
|
||||
|
||||
formdata = data_class()
|
||||
formdata.data = {'0': str(carddata.id)}
|
||||
formdata.user_id = local_user.id
|
||||
formdata.just_created()
|
||||
formdata.jump_status('new')
|
||||
formdata.store()
|
||||
|
||||
sql_queries.clear()
|
||||
resp = get_app(pub).get(sign_uri('/api/forms/test/list?filter-item=%s' % carddata.id, user=local_user))
|
||||
assert len(resp.json) == 1
|
||||
carddata_sql_queries = [q for q in sql_queries if 'FROM carddata' in q]
|
||||
assert len(carddata_sql_queries) == 1
|
||||
assert ' id = ' in carddata_sql_queries[0]
|
||||
|
||||
|
||||
def test_api_list_formdata_items_filter(pub, local_user):
|
||||
pub.role_class.wipe()
|
||||
role = pub.role_class(name='test')
|
||||
|
|
|
@ -99,7 +99,7 @@ def sql_queries(monkeypatch):
|
|||
|
||||
def cursor(*args, **kwargs):
|
||||
cur = old_cursor(*args, **kwargs)
|
||||
mocked_cur = mock.Mock(wraps=cur)
|
||||
mocked_cur = mock.MagicMock(wraps=cur)
|
||||
fpeters marked this conversation as resolved
Outdated
|
||||
old_execute = cur.execute
|
||||
|
||||
def execute(*args, **kwargs):
|
||||
|
|
|
@ -2064,13 +2064,10 @@ class FormPage(FormdefDirectoryBase):
|
|||
elif filter_field.type in ('item', 'items', 'bool', 'string', 'email', 'date'):
|
||||
criterias.append(criteria('f%s' % filter_field.id, filter_field_value, field=filter_field))
|
||||
if filter_field.type in ('item', 'items'):
|
||||
field_options = filter_field.get_options()
|
||||
if field_options and type(field_options[0]) in (list, tuple):
|
||||
for option in field_options:
|
||||
if filter_field_value in (option[0], option[-1]):
|
||||
filter_field_value = option[1]
|
||||
break
|
||||
criterias[-1]._label = '%s: %s' % (filter_field.label, filter_field_value)
|
||||
criterias[-1]._label = '%s: %s' % (
|
||||
filter_field.label,
|
||||
filter_field.get_display_value(filter_field_value),
|
||||
)
|
||||
|
||||
unknown_filters = sorted(filters_in_request - known_filters)
|
||||
if unknown_filters:
|
||||
|
|
|
@ -2183,6 +2183,32 @@ class ItemFieldMixin:
|
|||
for item in self.items or []:
|
||||
yield location, None, item
|
||||
|
||||
def get_display_value(self, value):
|
||||
data_source = data_sources.get_object(self.data_source)
|
||||
if data_source is None:
|
||||
return get_publisher().translate(value) or ''
|
||||
|
||||
if data_source.type == 'jsonp':
|
||||
if not get_session().jsonp_display_values:
|
||||
get_session().jsonp_display_values = {}
|
||||
return get_session().jsonp_display_values.get('%s_%s' % (data_source.get_jsonp_url(), value))
|
||||
|
||||
display_value = data_source.get_display_value(value)
|
||||
session = get_session()
|
||||
if (
|
||||
isinstance(session, BasicSession)
|
||||
and self.display_mode == 'autocomplete'
|
||||
and data_source
|
||||
and data_source.can_jsonp()
|
||||
):
|
||||
# store display value in session to be used by select2
|
||||
url = data_source.get_jsonp_url()
|
||||
if not session.jsonp_display_values:
|
||||
session.jsonp_display_values = {}
|
||||
session.jsonp_display_values['%s_%s' % (url, value)] = display_value
|
||||
|
||||
return display_value
|
||||
|
||||
|
||||
class ItemField(WidgetField, MapOptionsMixin, ItemFieldMixin):
|
||||
key = 'item'
|
||||
|
@ -2297,32 +2323,6 @@ class ItemField(WidgetField, MapOptionsMixin, ItemFieldMixin):
|
|||
# SingleSelectHintWidget with custom template
|
||||
kwargs['template-name'] = 'qommon/forms/widgets/select-timetable.html'
|
||||
|
||||
def get_display_value(self, value):
|
||||
data_source = data_sources.get_object(self.data_source)
|
||||
if data_source is None:
|
||||
return get_publisher().translate(value) or ''
|
||||
|
||||
if data_source.type == 'jsonp':
|
||||
if not get_session().jsonp_display_values:
|
||||
get_session().jsonp_display_values = {}
|
||||
return get_session().jsonp_display_values.get('%s_%s' % (data_source.get_jsonp_url(), value))
|
||||
|
||||
display_value = data_source.get_display_value(value)
|
||||
session = get_session()
|
||||
if (
|
||||
isinstance(session, BasicSession)
|
||||
and self.display_mode == 'autocomplete'
|
||||
and data_source
|
||||
and data_source.can_jsonp()
|
||||
):
|
||||
# store display value in session to be used by select2
|
||||
url = data_source.get_jsonp_url()
|
||||
if not session.jsonp_display_values:
|
||||
session.jsonp_display_values = {}
|
||||
session.jsonp_display_values['%s_%s' % (url, value)] = display_value
|
||||
|
||||
return display_value
|
||||
|
||||
def get_view_value(self, value, value_id=None, **kwargs):
|
||||
data_source = data_sources.get_object(self.data_source)
|
||||
if value and data_source is None:
|
||||
|
|
Loading…
Reference in New Issue
Qu'est-ce que ça implique ?
(ok il n'y a pas le commentaire initial dans la vue "fichiers modifiés", c'est répondu).