|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
Re: JSON method/view nameHi,
I have changed the grok.name directive and grok.JSONGrokker to make the suggestion of Martijn work. I added the folowing to the grok.name declaration in grokcore/component.py: def __call__(self, func): # grok.name can be used both as a class-level directive and # as a decorator for methods. Therefore we return a decorator # here, which may be used for methods, or simply ignored when # used as a directive. frame = sys._getframe(1) newName = frame.f_locals[self.dotted_name()] # delete the decorator from the class # so the decorator can be used more than once in the class del frame.f_locals[self.dotted_name()] self.set(func, newName) return func I changed the JSONGrokker in grok/meta.py: adapts = (context, layer) newName = grok.name.bind().get(method) if newName: name = newName setattr(method.im_class, newName, method) #XXX Is it possible to remove the copy of the method with # the oldname from the class? else: name = method.__name__ And to make sure it works ok I added a test in grok/tests/json. See the attached namedecorator.py. Is this the way you want it? Regards, Marc Martijn Faassen wrote: > Hey, > > Marc Rijken wrote: >> I want to use 'getAccounts.json' in the url for a JSON view. Because the >> method name of a grok.JSON view class will be used as name of the json >> view and because a method name normally can not contain a dot, I had to >> make a work around. The work around is: >> >> class JSONApi(grok.JSON): >> grok.context(tmx.ITopicMapX) >> >> def getAccounts(self): >> return { "status": "ok"} >> >> getAccounts.__name__ = 'getAccounts.json' >> >> setattr(JSONApi, 'getAccounts.json', JSONApi.getAccounts) >> >> This work around works ok, but it looks uggly. Is this is preferred way >> to do so or do you have a better solution? > > There's no official better solution. We should look into creating one, > possibly involving making @grok.name() a decorator that can be used in > this context. > > For a temporary somewhat prettier solution you could make your own > decorator that sets __name__ and does the setattr too (though I think > the latter is difficult as you wouldn't have access to the class yet > unless you resorted to frame hacks, I think). > > Alternatively you could create your own grok.View subclass that > implements its own render() method to handle JSON. You should then be > able to use grok.name(). > > Finally you could create an alternative baseclass along the lines of > grok.JSON and implement your own JSONGrokker that does the name inspection. > > If you're up to the challenge you'd be more than welcome to try to get > this into Grok itself. This applies to anyone else too, of course! I > think the @grok.name() decorator could be used: > > @grok.name('getAccounts.json) > def getAccounts(self): > .... > > Reusing a directive as a decorator is tricky however. We have a > precedent in grok.require, but it isn't the easiest thing to get going. > It'd be nice if we had more general infrastructure to accomplish this in > Martian. > > Regards, > > Martijn > > _______________________________________________ > Grok-dev mailing list > Grok-dev@... > https://mail.zope.org/mailman/listinfo/grok-dev """ The JSON grokker registers a view for each method of the JSON class. So we should be able to search for view by method name, even when the name has been changed with the grok.name directive. >>> grok.testing.grok(__name__) >>> mammoth = Mammoth() >>> from zope.publisher.browser import TestRequest >>> request = TestRequest() >>> from zope.component import getMultiAdapter >>> view = getMultiAdapter((mammoth, request), name='run.json') The 'run.json' method/view returns json data, but it looks just like python. >>> view() '{"me": "grok"}' Let's try calling another method:: >>> view = getMultiAdapter((mammoth, request), name='another.json') >>> view() '{"another": "grok"}' """ import grok class Mammoth(grok.Model): pass class MammothView(grok.JSON): grok.context(Mammoth) @grok.name('run.json') def run(self): return { 'me': 'grok' } @grok.name('another.json') def another(self): return { 'another': 'grok'} _______________________________________________ Grok-dev mailing list Grok-dev@... https://mail.zope.org/mailman/listinfo/grok-dev |
| Free embeddable forum powered by Nabble | Forum Help |