[Grok-dev] Re: Displaying an image stored on a grok.Model

Philipp von Weitershausen philipp at weitershausen.de
Mon Jan 21 12:57:11 EST 2008


Dirceu Pereira Tiegs wrote:
> Hey,
> 
> I'm using z3c.widget.image with the following code:
> 
> import grok
> from zope import interface, schema
> from zope.app.file.interfaces import IImage
> from z3c.widget.image.widget import ImageWidget
> 
> class z3cwidget_test(grok.Application, grok.Container):
>     pass
> 
> class IEvent(interface.Interface):
>     title = schema.TextLine(title=u"Title")
>     image = schema.Object(title=u"Image", schema=IImage, required=False)
> 
> class Event(grok.Model):
>     interface.implements(IEvent)
> 
>     def __init__(self, title, image=None):
>         super(Event, self).__init__()
>         self.title = title
>         self.image = image
> 
> class AddEvent(grok.AddForm):
>     form_fields = grok.AutoFields(Event)
>     form_fields['image'].custom_widget = ImageWidget
> 
>     @grok.action('Add event')
>     def add(self, **data):
>         obj = Event(**data)
>         name = data['title'].lower().replace(' ', '_')
>         self.context[name] = obj
> 
> class Index(grok.DisplayForm):
>     grok.context(Event)
> 
> It works, but I can't figure out how to show the image on a page
> template. Any hints?

You have two choices:

a) Write a view for IEvent that will show the image to the browser:

   class ShowEventImage(grok.View):
       grok.context(IEvent)  # default
       grok.name('image')

       def render(self):
           content_type = self.context.image.contentType
           self.response.setHeader('Content-Type', content_type)
           return str(self.context.image.data)
           # not very optimized, better write image to a tempfile
           # and return the filehandle for better memory consumption

b) Make the image traversable:

   class EventTraverser(grok.Traverser):
       grok.context(IEvent)  # default

       def traverse(self, name):
           if name == 'image':
               return self.context.image

You can also put this right on the Event model:

   class Event(grok.Model):
       interface.implements(IEvent)

       def __init__(self, title, image=None):
           super(Event, self).__init__()
           self.title = title
           self.image = image

       def traverse(self, name):
           if name == 'image':
               return self.image


More information about the Grok-dev mailing list