misc: add with_custom_view filter (#48553)

This commit is contained in:
Lauréline Guérin 2020-11-19 11:53:02 +01:00
parent 44b27d2164
commit b723546cf5
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
6 changed files with 172 additions and 39 deletions

View File

@ -223,22 +223,82 @@ def test_template_access(pub):
carddef.name = 'foo'
carddef.fields = [
StringField(id='1', label='Test', type='string', varname='foo'),
StringField(id='2', label='key', type='string', varname='key'),
]
carddef.store()
carddef.data_class().wipe()
for i in range(10):
carddata = carddef.data_class()()
carddata.data = {'1': 'blah'}
if i % 3 == 0:
carddata.data = {'1': 'blah'}
if i % 3 == 1:
carddata.data = {'1': 'foo'}
if i % 3 == 2:
carddata.data = {'1': 'bar'}
carddata.data['2'] = str(i)
carddata.just_created()
carddata.store()
context = pub.substitutions.get_context_variables(mode='lazy')
tmpl = Template('{{cards.foo.objects|filter_by:"foo"|filter_value:"blah"|count}}')
assert tmpl.render(context) == '10'
tmpl = Template('{{cards.foo.objects|filter_by:"foo"|filter_value:"blah"|count}}')
assert tmpl.render(context) == '4'
tmpl = Template('{{cards|objects:"foo"|filter_by:"foo"|filter_value:"blah"|count}}')
assert tmpl.render(context) == '10'
assert tmpl.render(context) == '4'
pub.custom_view_class.wipe()
custom_view1 = pub.custom_view_class()
custom_view1.title = 'datasource card view'
custom_view1.formdef = carddef
custom_view1.columns = {'list': [{'id': 'id'}, {'id': 'time'}, {'id': 'status'}]}
custom_view1.filters = {'filter-1': 'on', 'filter-1-value': 'blah'}
custom_view1.visibility = 'datasource'
custom_view1.order_by = '-f2'
custom_view1.store()
custom_view2 = pub.custom_view_class()
custom_view2.title = 'shared card view'
custom_view2.formdef = carddef
custom_view2.columns = {'list': [{'id': 'id'}, {'id': 'time'}, {'id': 'status'}]}
custom_view2.filters = {'filter-1': 'on', 'filter-1-value': 'foo'}
custom_view2.visibility = 'any'
custom_view2.order_by = 'f2'
custom_view2.store()
custom_view3 = pub.custom_view_class()
custom_view3.title = 'private card view'
custom_view3.formdef = carddef
custom_view3.columns = {'list': [{'id': 'id'}]}
custom_view3.filters = {}
custom_view3.visibility = 'owner'
custom_view3.usier_id = 42
custom_view3.order_by = 'id'
custom_view3.store()
tmpl = Template('{{cards.foo.objects|with_custom_view:"datasource-card-view"|count}}')
assert tmpl.render(context) == '4'
tmpl = Template('{{cards|objects:"foo"|with_custom_view:"datasource-card-view"|count}}')
assert tmpl.render(context) == '4'
tmpl = Template('{% for data in cards|objects:"foo"|with_custom_view:"datasource-card-view" %}{{ data.internal_id }},{% endfor %}')
assert tmpl.render(context) == '10,7,4,1,'
tmpl = Template('{{cards.foo.objects|with_custom_view:"shared-card-view"|count}}')
assert tmpl.render(context) == '3'
tmpl = Template('{{cards|objects:"foo"|with_custom_view:"shared-card-view"|count}}')
assert tmpl.render(context) == '3'
tmpl = Template('{% for data in cards|objects:"foo"|with_custom_view:"shared-card-view" %}{{ data.internal_id }},{% endfor %}')
assert tmpl.render(context) == '2,5,8,'
tmpl = Template('{{cards.foo.objects|with_custom_view:"private-card-view"|count}}')
assert tmpl.render(context) == '0'
tmpl = Template('{{cards|objects:"foo"|with_custom_view:"private-card-view"|count}}')
assert tmpl.render(context) == '0'
tmpl = Template('{{cards.foo.objects|with_custom_view:"unknown"|count}}')
assert tmpl.render(context) == '0'
tmpl = Template('{{cards|objects:"foo"|with_custom_view:"unknown"|count}}')
assert tmpl.render(context) == '0'
def test_data_source_access_invalid_id(pub):

View File

@ -1134,25 +1134,30 @@ def test_lazy_formdata_queryset_get_from_first(pub, variable_test_data):
assert tmpl.render(context) == 'bar'
def test_lazy_global_forms(pub, variable_test_data):
lazy_formdata = variable_test_data
formdef = lazy_formdata._formdef
def test_lazy_global_forms(pub):
FormDef.wipe()
formdef = FormDef()
formdef.name = 'foobarlazy'
formdef.fields = [
fields.StringField(id='1', label='Test', type='string', varname='foo'),
fields.StringField(id='2', label='key', type='string', varname='key'),
]
formdef.store()
data_class = lazy_formdata._formdef.data_class()
formdef.data_class().wipe()
for i in range(6):
formdata = data_class()
formdata.data = {'0': 'bar'}
formdata = formdef.data_class()()
formdata.data = {'1': 'bar', '2': str(i)}
formdata.just_created()
formdata.store()
for i in range(4):
formdata = data_class()
formdata.data = {'0': 'foo'}
formdata = formdef.data_class()()
formdata.data = {'1': 'foo', '2': str(i+6)}
formdata.just_created()
formdata.jump_status('finished')
formdata.store()
formdata = data_class()
formdata.data = {'0': 'bar'}
formdata = formdef.data_class()()
formdata.data = {'1': 'bar'}
formdata.status = 'draft'
formdata.store()
@ -1161,8 +1166,53 @@ def test_lazy_global_forms(pub, variable_test_data):
tmpl = Template('{{forms.foobarlazy.slug}}')
assert tmpl.render(context) == 'foobarlazy'
tmpl = Template('{{forms|objects:"foobarlazy"|filter_by:"foo_foo"|filter_value:"bar"|count}}')
assert tmpl.render(context) == '7'
tmpl = Template('{{forms|objects:"foobarlazy"|filter_by:"foo"|filter_value:"bar"|count}}')
assert tmpl.render(context) == '6'
pub.custom_view_class.wipe()
custom_view1 = pub.custom_view_class()
custom_view1.title = 'datasource form view'
custom_view1.formdef = formdef
custom_view1.columns = {'list': [{'id': 'id'}, {'id': 'time'}, {'id': 'status'}]}
custom_view1.filters = {'filter-1': 'on', 'filter-1-value': 'bar'}
custom_view1.visibility = 'datasource'
custom_view1.order_by = '-f2'
custom_view1.store()
custom_view2 = pub.custom_view_class()
custom_view2.title = 'shared form view'
custom_view2.formdef = formdef
custom_view2.columns = {'list': [{'id': 'id'}, {'id': 'time'}, {'id': 'status'}]}
custom_view2.filters = {'filter-1': 'on', 'filter-1-value': 'foo'}
custom_view2.visibility = 'any'
custom_view2.order_by = 'f2'
custom_view2.store()
custom_view3 = pub.custom_view_class()
custom_view3.title = 'private form view'
custom_view3.formdef = formdef
custom_view3.columns = {'list': [{'id': 'id'}]}
custom_view3.filters = {}
custom_view3.visibility = 'owner'
custom_view3.usier_id = 42
custom_view3.order_by = 'id'
custom_view3.store()
tmpl = Template('{{forms|objects:"foobarlazy"|with_custom_view:"datasource-form-view"|count}}')
assert tmpl.render(context) == '6'
tmpl = Template('{% for data in forms|objects:"foobarlazy"|with_custom_view:"datasource-form-view" %}{{ data.internal_id }},{% endfor %}')
assert tmpl.render(context) == '6,5,4,3,2,1,'
tmpl = Template('{{forms|objects:"foobarlazy"|with_custom_view:"shared-form-view"|count}}')
assert tmpl.render(context) == '4'
tmpl = Template('{% for data in forms|objects:"foobarlazy"|with_custom_view:"shared-form-view" %}{{ data.internal_id }},{% endfor %}')
assert tmpl.render(context) == '7,8,9,10,'
tmpl = Template('{{forms|objects:"foobarlazy"|with_custom_view:"private-form-view"|count}}')
assert tmpl.render(context) == '0'
tmpl = Template('{{forms|objects:"foobarlazy"|with_custom_view:"unknown"|count}}')
assert tmpl.render(context) == '0'
def test_lazy_variables(pub, variable_test_data):

View File

@ -174,25 +174,6 @@ class CardDef(FormDef):
return custom_view
return None
@classmethod
def get_data_source_criterias(cls, carddef, custom_view):
from wcs.backoffice.management import FormPage
form_page = FormPage(formdef=carddef, view=custom_view, update_breadcrumbs=False)
criterias = form_page.get_view_criterias()
selected_filter = custom_view.get_filter()
if selected_filter and selected_filter != 'all':
if selected_filter == 'pending':
applied_filters = ['wf-%s' % x.id for x in carddef.workflow.get_not_endpoint_status()]
elif selected_filter == 'done':
applied_filters = ['wf-%s' % x.id for x in carddef.workflow.get_endpoint_status()]
else:
applied_filters = ['wf-%s' % selected_filter]
if applied_filters:
criterias.append(Contains('status', applied_filters))
return criterias
@classmethod
def get_data_source_items(cls, data_source_id, query=None, limit=None,
custom_view=None, get_by_id=None, get_by_text=None):
@ -211,7 +192,7 @@ class CardDef(FormDef):
if not custom_view:
return []
order_by = custom_view.order_by
criterias.extend(cls.get_data_source_criterias(carddef, custom_view))
criterias.extend(custom_view.get_criterias(formdef=carddef))
for criteria in criterias:
if not Template.is_template_string(criteria.value):
continue
@ -269,7 +250,7 @@ class CardDef(FormDef):
return []
varnames = []
from .fields import Field
for criteria in cls.get_data_source_criterias(carddef, custom_view):
for criteria in custom_view.get_criterias(formdef=carddef):
if not isinstance(criteria.value, str):
continue
varnames.extend(Field.get_referenced_varnames(formdef, criteria.value))

View File

@ -22,7 +22,7 @@ from quixote import get_publisher
from wcs.carddef import CardDef
from wcs.formdef import FormDef
from wcs.qommon.storage import StorableObject, Equal
from wcs.qommon.storage import StorableObject, Equal, Contains
from wcs.qommon.misc import simplify
from .qommon.misc import xml_node_text
@ -142,6 +142,30 @@ class CustomView(StorableObject):
def get_default_filters(self):
return [key[7:] for key in self.filters if key.startswith('filter-')]
def get_criterias(self, formdef=None):
from wcs.backoffice.management import FormPage
if formdef is not None:
assert formdef.id == self.formdef_id
else:
formdef = self.formdef
form_page = FormPage(formdef=formdef, view=self, update_breadcrumbs=False)
criterias = form_page.get_view_criterias()
selected_filter = self.get_filter()
if selected_filter and selected_filter != 'all':
if selected_filter == 'pending':
applied_filters = ['wf-%s' % x.id for x in formdef.workflow.get_not_endpoint_status()]
elif selected_filter == 'done':
applied_filters = ['wf-%s' % x.id for x in formdef.workflow.get_endpoint_status()]
else:
applied_filters = ['wf-%s' % selected_filter]
if applied_filters:
criterias.append(Contains('status', applied_filters))
return criterias
def export_to_xml(self, charset=None):
root = ET.Element(self.xml_root_node)
fields = [

View File

@ -605,10 +605,15 @@ def pending(queryset):
def objects(forms_source, slug):
if hasattr(slug, 'get_value'):
slug = slug.get_value() # unlazy
# assume formdef_source is an instance of CardsSouce of FormsSource
# assume formdef_source is an instance of CardsSource of FormsSource
return getattr(forms_source, slug).objects
@register.filter
def with_custom_view(queryset, custom_view_slug):
return queryset.with_custom_view(custom_view_slug)
@register.filter
def order_by(queryset, attribute):
if hasattr(attribute, 'get_value'):

View File

@ -91,6 +91,19 @@ class LazyFormDefObjectsManager(object):
break
return self._clone(self._criterias + [Equal('status', wf_status)])
def with_custom_view(self, custom_view_slug):
lookup_criterias = [
Equal('formdef_type', self._formdef.xml_root_node),
Equal('formdef_id', self._formdef.id),
NotEqual('visibility', 'owner'),
Equal('slug', custom_view_slug),
]
try:
custom_view = get_publisher().custom_view_class.select(lookup_criterias)[0]
except IndexError:
return self._clone([Equal('status', '_none')])
return self._clone(self._criterias + custom_view.get_criterias(), order_by=custom_view.order_by)
def exclude_self(self):
assert self._formdata
return self._clone(self._criterias + [NotEqual('id', str(self._formdata.id))])