I need to restrict the creation of a custom (Dexterity) content type to only one instance (per site). How? It should be trivial...
Add an event subscriber for
zope.lifecycleevent.interfaces.IObjectAddedEvent that would implement such a check e.g. by performing a catalog search. Raise an exception in case ...
Disclaimer: exceptions from event handlers are possibly swallowed somewhere in Plone
And there is also some "magic" in Zope/OFS/ObjectManager ... setting
__replaceable__ = UNIQUE on an object may help, perhaps.
I had a similar requirement which had some edge cases: do test the validator that the catalog search is not finding the singleton item you just created and therefore blocks.
(Or for example when moving the Item, which would trigger a new ObjectAddedEvent.)
Try and see if disabling "Implicitly allowed" (or global allow, or something) for the content type is good enough.
This can be set in the ( /@@content-controlpanel ) control panel
Replying to myself:
I added a init to the content type class and used portal_catalog to check the number of indexed objects of that type. Something like:
from plone import api from plone. dexterity.content import Item class MyItem(Item): def __init__(self, id=None, **kwargs): catalog = api.portal.get_tool('portal_catalog') brains = catalog(portal_type='mytype') if brains: raise Exception('Only one "mytype" object is allowed per Plone instance') super(MyItem, self).__init__(id, **kwargs)
Thanks to all.