formdatas: add access from formdata to reverse_links (#57964) #766
|
@ -5440,3 +5440,101 @@ def test_page_field_var(pub, formdef):
|
|||
|
||||
assert 'form_var_page' not in formdata.get_substitution_variables()
|
||||
assert 'page' not in LazyFormData(formdata).var.inspect_keys()
|
||||
|
||||
|
||||
def test_reverse_links(pub):
|
||||
CardDef.wipe()
|
||||
carddef1 = CardDef()
|
||||
carddef1.name = 'Card 1'
|
||||
carddef1.digest_templates = {'default': '{{form_var_name1}}'}
|
||||
carddef1.fields = [
|
||||
fields.StringField(id='0', label='string', varname='name1'),
|
||||
]
|
||||
carddef1.store()
|
||||
carddata1 = carddef1.data_class()()
|
||||
carddata1.data = {
|
||||
'0': 'foo1',
|
||||
}
|
||||
carddata1.just_created()
|
||||
carddata1.store()
|
||||
|
||||
ds = {'type': 'carddef:%s' % carddef1.url_name}
|
||||
|
||||
carddef2 = CardDef()
|
||||
carddef2.name = 'Card 2'
|
||||
carddef2.digest_templates = {'default': '{{form_var_name2}}'}
|
||||
carddef2.fields = [
|
||||
fields.StringField(id='0', label='string', varname='name2'),
|
||||
fields.ItemField(id='1', label='string', varname='foo', data_source=ds),
|
||||
]
|
||||
carddef2.store()
|
||||
carddata2 = carddef2.data_class()()
|
||||
carddata2.data = {
|
||||
'0': 'foo2',
|
||||
'1': str(carddata1.id),
|
||||
}
|
||||
carddata2.data['1_display'] = carddef2.fields[1].store_display_value(carddata1.data, '0')
|
||||
carddata2.data['1_structured'] = carddef2.fields[1].store_structured_value(carddata1.data, '0')
|
||||
carddata2.just_created()
|
||||
carddata2.store()
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'foobar'
|
||||
formdef.fields = [fields.ItemField(id='0', label='string', varname='bar', data_source=ds)]
|
||||
formdef.store()
|
||||
formdata1 = formdef.data_class()()
|
||||
formdata1.data = {
|
||||
'0': str(carddata1.id),
|
||||
}
|
||||
formdata1.data['0_display'] = formdef.fields[0].store_display_value(carddata1.data, '0')
|
||||
formdata1.data['0_structured'] = formdef.fields[0].store_structured_value(carddata1.data, '0')
|
||||
formdata1.just_created()
|
||||
formdata1.store()
|
||||
formdata2 = formdef.data_class()()
|
||||
formdata2.data = {
|
||||
'0': str(carddata1.id),
|
||||
}
|
||||
formdata2.data['0_display'] = formdef.fields[0].store_display_value(carddata1.data, '0')
|
||||
formdata2.data['0_structured'] = formdef.fields[0].store_structured_value(carddata1.data, '0')
|
||||
formdata2.just_created()
|
||||
formdata2.store()
|
||||
|
||||
# test reverse relation
|
||||
carddef1.store() # build & store reverse_relations
|
||||
pub.substitutions.reset()
|
||||
pub.substitutions.feed(pub)
|
||||
pub.substitutions.feed(carddef1)
|
||||
pub.substitutions.feed(carddata1)
|
||||
context = pub.substitutions.get_context_variables(mode='lazy')
|
||||
assert len(context['form_reverse_links_formdef_foobar_bar']) == 2
|
||||
assert context['form_reverse_links_formdef_foobar_bar_0_form_internal_id'] == formdata1.id
|
||||
assert context['form_reverse_links_formdef_foobar_bar_1_form_internal_id'] == formdata2.id
|
||||
assert len(context['form_reverse_links_carddef_card_2_foo']) == 1
|
||||
assert context['form_reverse_links_carddef_card_2_foo_0_form_internal_id'] == carddata2.id
|
||||
|
||||
# test with natural id
|
||||
carddef1.id_template = 'X{{ form_var_name1 }}Y'
|
||||
carddef1.store()
|
||||
carddata1.store()
|
||||
assert carddata1.id_display == 'Xfoo1Y'
|
||||
carddata2.data['1'] = carddata1.get_natural_key()
|
||||
carddata2.store()
|
||||
formdata1.data['0'] = carddata1.get_natural_key()
|
||||
formdata1.just_created()
|
||||
formdata1.store()
|
||||
formdata2 = formdef.data_class()()
|
||||
formdata2.data['0'] = carddata1.get_natural_key()
|
||||
formdata2.just_created()
|
||||
formdata2.store()
|
||||
|
||||
pub.substitutions.reset()
|
||||
pub.substitutions.feed(pub)
|
||||
pub.substitutions.feed(carddef1)
|
||||
pub.substitutions.feed(carddata1)
|
||||
context = pub.substitutions.get_context_variables(mode='lazy')
|
||||
assert len(context['form_reverse_links_formdef_foobar_bar']) == 2
|
||||
assert context['form_reverse_links_formdef_foobar_bar_0_form_internal_id'] == formdata1.id
|
||||
assert context['form_reverse_links_formdef_foobar_bar_1_form_internal_id'] == formdata2.id
|
||||
assert len(context['form_reverse_links_carddef_card_2_foo']) == 1
|
||||
assert context['form_reverse_links_carddef_card_2_foo_0_form_internal_id'] == carddata2.id
|
||||
|
|
|
@ -991,6 +991,10 @@ class LazyFormData(LazyFormDef):
|
|||
|
||||
return LazyFormDataLinks(self._formdata)
|
||||
|
||||
@property
|
||||
def reverse_links(self):
|
||||
return LazyFormDataReverseLinks(self._formdata)
|
||||
|
||||
@property
|
||||
def workflow_email(self):
|
||||
# form_ workflow_email_ <slug (action varname)> _ <index> _ etc.
|
||||
|
@ -1057,6 +1061,97 @@ class LazyFormData(LazyFormDef):
|
|||
raise
|
||||
|
||||
|
||||
class LazyFormDataReverseLinks:
|
||||
def __init__(self, formdata):
|
||||
self._formdata = formdata
|
||||
|
||||
_relations = None
|
||||
|
||||
@property
|
||||
def relations(self):
|
||||
if self._relations is not None:
|
||||
return self._relations
|
||||
self._relations = {}
|
||||
for relation in self._formdata.formdef.reverse_relations:
|
||||
if not relation['varname']:
|
||||
continue
|
||||
key = '%s_%s' % (relation['obj'], relation['varname'])
|
||||
key = key.replace(':', '_').replace('-', '_')
|
||||
self._relations[key] = relation
|
||||
return self._relations
|
||||
|
||||
def inspect_keys(self):
|
||||
return self.relations.keys()
|
||||
|
||||
def __getitem__(self, key):
|
||||
if not isinstance(key, str):
|
||||
raise KeyError(str(key))
|
||||
|
||||
relation = self.relations[key]
|
||||
|
||||
formdef_type, formdef_slug = relation['obj'].split(':')
|
||||
formdef_class = FormDef
|
||||
if formdef_type == 'carddef':
|
||||
formdef_class = CardDef
|
||||
formdef = formdef_class.get_by_slug(formdef_slug, ignore_errors=True)
|
||||
if formdef is None:
|
||||
return None
|
||||
lazy_manager = LazyFormDefObjectsManager(formdef=formdef)
|
||||
formdatas = [
|
||||
LazyFormDataReverseLinksItem(formdata)
|
||||
for formdata in lazy_manager.filter_by(relation['varname']).apply_filter_value(
|
||||
str(self._formdata.get_natural_key())
|
||||
|
||||
)
|
||||
]
|
||||
if not formdatas:
|
||||
return []
|
||||
return LazyFormDataReverseLinksItems(formdatas)
|
||||
|
||||
|
||||
class LazyFormDataReverseLinksItems:
|
||||
inspect_collapse = True
|
||||
|
||||
def __init__(self, formdatas):
|
||||
self._formdatas = formdatas
|
||||
|
||||
def inspect_keys(self):
|
||||
return [str(x) for x in range(len(self._formdatas))]
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
key = int(key)
|
||||
except ValueError:
|
||||
raise KeyError
|
||||
return self._formdatas[key]
|
||||
|
||||
def __len__(self):
|
||||
return len(self._formdatas)
|
||||
|
||||
def __iter__(self):
|
||||
yield from self._formdatas
|
||||
|
||||
|
||||
class LazyFormDataReverseLinksItem:
|
||||
inspect_collapse = True
|
||||
|
||||
def __init__(self, formdata):
|
||||
self._formdata = formdata
|
||||
|
||||
def inspect_keys(self):
|
||||
return ['form']
|
||||
|
||||
@property
|
||||
def form(self):
|
||||
fpeters
commented
Et ici aussi, get_natural_key ? Et ici aussi, get_natural_key ?
|
||||
return self._formdata
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
return getattr(self, key)
|
||||
except AttributeError:
|
||||
compat_dict = CompatibilityNamesDict({'form': self._formdata})
|
||||
return compat_dict[key]
|
||||
|
||||
|
||||
class LazyFormDataVar:
|
||||
def __init__(self, fields, data, formdata=None, base_formdata=None):
|
||||
self._fields = fields
|
||||
|
|
Loading…
Reference in New Issue
Peut-être get_natural_key(), pour prendre en compte la possibilité d'id personnalisés ?