Browser views: inherit from object or BrowserView from Five/Plone

Martin Aspeli optilude at gmx.net
Wed Apr 18 20:14:31 UTC 2007


Maurits van Rees wrote:
> Hi Martin,
> 
> Martin Aspeli, on 2007-04-18:
>>> Inherit from object
>>> -------------------
>>>
>>>     class MyView(object):
>>>         def __init__(self, context, request):
>>>             self.context = context
>>>             self.request = request
>>>
>>> The view is not Acquisition wrapped, which means that any permission
>>> you set in the configure.zcml is ignored and everyone can see this
>>> view, right?
>>>
>>> You define your own __init__() so you can handle the context anyway you
>>> please.
>>>
>> This doesn't work in Zope 2. You need to inherit from Acquisition.Explicit
>> at a minimum, or you'll get strange security errors.
> 
> I switched eXtremeManagement browser views from object to Five's
> BrowserView because it is supposedly better.  Diffs are here:
> 
> http://dev.plone.org/collective/changeset/40756
> http://dev.plone.org/collective/changeset/40771
> 
> But it worked fine before those changes.  I did not see security
> errors.  That is on Zope 2.9, Plone 2.5.
> 
> It might depend on what exactly is done in those browser views, but
> the things that my browser views do apparently do not cause strange
> security errors.  Maybe I was just lucky. :)

Probably you were, yes. Trust me, you need acquisition in there.

>>> Inherit from Five
>>> -----------------
>>>
>>>     from Products.Five.browser import BrowserView
>>>     class MyView(BrowserView):
>>>
>>> The view is Acquisition wrapped, so Zope security kicks in, which is
>>> probably good.
>>>
>>> If you do not overwrite the __init__() you can use the context with
>>> self.context.
>>>
>> This is the correct approach, imho. However, note that whe you access
>> 'self.context' it will be aq wrapped in the context of the view (since it
>> inherits from Acquisition.Explicit). If self.context is a content item, it
>> also has an inner acquisition chain from its containment. If you do
>> something on the object that needs to e.g. acquire tools or perform explicit
>> security checks, you probably want the inner chain since the outer one
>> contains the view.
> 
> So getToolByName(self.context, 'portal_catalog') could go wrong?  It
> works for me.

It'll work, but it's more subtle than that. To understand what's going 
on, you need to put a pdb breakpoint in a method in a view, e.g. try:

class MyView(BrowserView):

     def __call__(self):

> Come to think of it, it also seems to be fine when I do this:
> 
>     getToolByName(self, 'portal_catalog')
> 
> where self is the View.
> 
> Am I overlooking anything?
> 
>> Therefore, I find it much safer to always do;
>>
>> from Acquisition import aq_inner
>> from Products.Five.browser import BrowserView
>>
>> class MyView(BrowserView):
>>
>>     def some_method(self):
>>         context = aq_inner(self.context)
>>         # use context in some way
> 
> I think I will try that too.
> 
>>> Inherit from Plone
>>> ------------------
>>>
>>>     from Products.CMFPlone import utils
>>>     class MyView(utils.BrowserView):
>> I really hate this view, and we're not using it any more in new views in
>> Plone 3.
> 
> I will avoid this too then.
> 
>> Apart from a conscious move away from Products.CMFPlone.utils.BrowserView,
>> I'm not aware of any incompatabilities between the use of views in Plone 2.5
>> and Plone 3.
> 
> Great, thanks.
> 
> 





More information about the Product-Developers mailing list