Context aware invariant on z3c.form dx add form

  • I have a behavior schema for a Dexterity type license.
  • it has two fields year and person-number - both in catalog
  • I want to test if a combination of these two values already exists under my current folder.
    @invariant
    def check_combination_exists(data)
       ....

Plan is to query the catalog with year, person-number and path of the current folder. If there is result, the invariant fails.

Problem: I have no context in there, only a z3c.form.validator.Data object.
Even data.__context__ is None in an add-form as it seems.

Any ideas how to get the add-context of an add-form in the invariant?

What is your problem? Getting hold of the portal_catalog?

No, catalog, that's easy (getSite() or api.portal.get() or direct api.portal.get_tool(..).

Problem is to get the current context of the form in order to get the path so I can feed it in a ExtendedPathIndex query.

Perhaps request.PUBLISHED ?
Otherwise grab request.URL, extract the relative path, traverse to this object...

1 Like

I a "normal" (e.g. Web request) setup, the Plone portal is registered as a "site" (a notion of the Zope component architecture). If this is the case, then the Plone portal is available as a Products.CMFPlone.interfaces.siteroot.IPloneSiteRoot utility. From there, you can access all portal tools in the normal way (--> e.g. getToolByName).

Note that in special setups (test, script), this may not be the case.

Thanks, but as said, that's not the problem. I look for the current context of the dexterity add-form if I am in an invariant.

That is the hint I was looking for!

from zope.globalrequest import getRequest()
addview = getRequest().PUBLISHED
container = addview.context

Thanks!

3 Likes

FTR: Sometimes the add-view has itself as context and on it the real context. I worked around with this ugly code for now.

        addview = getRequest().PUBLISHED
        container = addview.context
        try:
            # sometimes double wrapped
            container = container.context
        except AttributeError:
            pass
2 Likes

You use a custom addform and then validate in the data in the "save" button handler/action?

Sure, but just for an invariant check this is quite some effort. In fact I thought about making it so, but refused to bloat my code and better ask here :wink: