Silva altepeter.net Not logged in.

Family

Videos

Technology Stuff

Articles

Fun

Silva Products

Web Design

VIVO Javascript Framework

Photo Galleries

Contact Us

Blog

Notes about setting 'model' in Zope's REQUEST, and avoiding subtle bugs.

I'm writing this to express a "lesson learned" / "gotcha":

I just spent some time tracking down an obscure bug that was breaking things in the SNN News Item publish tab.  This bug surfaces if you attempt to future-publish a News Item (article or agenda item) by clicking "approve for future".  In Silva 2.0, you'll get an AttributeError: @@additional_status_action.  This bug was present in 1.6, but probably didn't surface as much.  It is possible (though not verified) that after approving for future, clicking actions on the subsequent page would come up with errors.

It turns out the problem was in NewsItem.get_intro.  There's a comment in there about "something" in the code needing request['model'] set.  I've needed to set (or replace) request['model'] a few times in various projects, and I've (re)learned a few important things:

1) ALWAYS save the model before running the code that needs a new model, and then RESTORE the saved model.  If there was no model previously, DELETE what you put in there.

2) The REQUEST object contains a LOT of scary magic.   Scary magic of the sort that request.model != request['model'].

In restricted python (PythonScripts), you can't set request.model.  BUT, you can set request['model'].  The latter puts 'model' in the dictionary "request.other".

In unrestricted, product code, you can do either.  But note that setting request.model DOES NOT put 'model' in the 'other' dictionary!  It sets an attribute on the request object with a name of 'model'.  That's a very important distiction!

The view registry (where 'model' typically gets set non-public processing), sets self.REQUEST['model'].  This placed 'model' in the 'other' dictionary, and as such 'model' is visible in the error log.

The get_intro code did used the alternate method, of setting self.REQUEST.model.  Since this is now an attribute of REQUEST, it isn't printed in the error log, and it is not obvious that there are now effectively TWO 'model' attributes in the REQUEST.

SilvaObject.view_version explicitly sets both, e.g.:
request.model = version
request.other['model'] = version

Note that I believe view_version is where the public rendering gets request.model.

Neither of these are meant to be called during other processing, as they overwrite the existing models.  

Well, there you have it.  I'm not sure what else to say other than to watch out when changing (or setting) request.model!