showing an image attachment in a Django template

14 views
Skip to first unread message

rossdavidh

unread,
May 12, 2011, 8:18:28 PM5/12/11
to CouchDB-Python
Hi, I'm attempting to use couchdb for the first time, in a django
app. I have it working for text, but when I attempt to display an
attached image I seem to be missing something. I can lay hold of the
couchdb document, and display elements from it in the django template,
but I don't seem to be able to find the right syntax to show an image
attached to the document.

I was thinking this can't be an exotic or rare thing to do, so I put
the question on StackOverflow:
http://stackoverflow.com/questions/5940732/how-to-display-a-couchdb-image-attachment-in-a-django-template

Now, when I try to find solutions to this using Google my own
stackoverflow question is coming up as the top search result so that
doesn't seem like a good sign.

Can anyone point me to an example (views.py, urls.py, and template) of
using couchdb attachments in Django?

Many thanks.

Kxepal

unread,
May 13, 2011, 1:32:16 AM5/13/11
to couchdb...@googlegroups.com
Hi!
You code is a little incorrect. Yes, attachments is a part of document, but in same time they are not included into. Document only knows about what attachments it has, their size and mimetype. To get attachments you should use `db.get_attachment` method, but it would return to you file-like object (StringIO AFAIK). Thats probably is not what you need. You need to build url of this attachment and write it into img tag, right? So try this one:
db.resource(docid)(filename).url
and you would get full url to your filename that has been attached to docid within db.

Hope that would help(:

Matt Goodall

unread,
May 13, 2011, 7:07:15 AM5/13/11
to couchdb...@googlegroups.com
Database.get_attachment only returns a StringIO for small attachments. Anything over a certain size (8k, I think) will return a http.ResponseBody instance to read from.

However, since both StringIO and ResponseBody are readable and file-like it shouldn't matter to application code. Just make sure you read all the bytes or explicitly close whatever is returned.

- Matt

 

Hope that would help(:

--
You received this message because you are subscribed to the Google Groups "CouchDB-Python" group.
To post to this group, send email to couchdb...@googlegroups.com.
To unsubscribe from this group, send email to couchdb-pytho...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/couchdb-python?hl=en.

rossdavidh

unread,
May 13, 2011, 1:54:59 PM5/13/11
to CouchDB-Python
I got really excited about this:
image_url = docs(id)('dog.jpg').url

... but when I try it I get:
'Database' object is not callable

...and same result when I try this:
image_url = docs(id)('_attachments')('dog.jpg').url

It's odd because I was able to do this previously, when the code was
just residing on my laptop, simply by doing:

pre_markdown_text = pre_markdown_text.replace('imagepath','http://
localhost:5984/docs/' + doc['title'] + '/')
text_marked_down = markdown.markdown(pre_markdown_text)

...then, when I passed 'text_marked_down' to the template it was able
to render the image perfectly well. But,
now that I've copied the code from my little laptop to the server, I
can't seem to find a way to make it work
(and obviously an image url with "localhost" in there will not do).

What's more surprising to me is that I'm not finding an example of
this anywhere on the web. When I am
trying to do something that's pretty ordinary (show an image in a web
page) and I'm finding no examples of
how to do it, I start to think that I have gone wrong somewhere.

Do others avoid using couchdb to serve up the images inside django (or
any other framework)? I would have
thought that using _attachments would be a great way to do it, but I'm
starting to wonder if I have picked
the wrong strategy here. Should I just be putting the images in
Django's "static" folder instead?

thanks,
ross

Kxepal

unread,
May 13, 2011, 2:01:36 PM5/13/11
to couchdb...@googlegroups.com
On Friday, May 13, 2011 9:54:59 PM UTC+4, rossdavidh wrote:
I got really excited about this:
image_url = docs(id)('dog.jpg').url

rossdavidh

unread,
May 13, 2011, 3:21:46 PM5/13/11
to CouchDB-Python
D'oh! You are correct, my apologies. However, when I use:

image_url = docs.resource(id)('dog.jpg').url

...I get:
'Resource' object has no attribute 'url'

Any ideas? Many thanks again for the help.

ross

rossdavidh

unread,
May 13, 2011, 3:31:58 PM5/13/11
to CouchDB-Python
Oh, I see, it's "uri" instead of "url". However, now when I try that
it gives me a url starting with "http://127.0.0.1:5894/docs/" [etc.],
and while that
may in fact be how you would get to the image when you're on the
server (which is where the python code is when it's determining the
uri), it's
not what the client's browser should use to get to the image once it
has loaded the template-based html.

Which brings me back to the other question: am I just trying to do
this the wrong way? Is couchdb only intended to server up attachments
when
it's sitting on the client's device (e.g. a mobile device app that
occasionally syncs up with a central server), and it's not suitable
for serving
up web page images from a conventional client browser that resides on
a device different than the one where the couchdb database is?

thanks,
ross

Kxepal

unread,
May 13, 2011, 3:56:26 PM5/13/11
to couchdb...@googlegroups.com
> Oh, I see, it's "uri" instead of "url".
Strange, because it should be url. And I couldn't remember when it was uri.


> However, now when I try that it gives me a url starting with "http://127.0.0.1:5894/docs/" [etc.]
It's because how you have establish connection to your server/database. Is your CouchDB have public access?
Anyway, there are two options: use public access to your CouchDB server or you could try to use couchdb.http.urljoin function - it actually does same thing as I wrote for resource, but only builds url:

from couchdb.http import urljoin
...
if docid not in db:
  raise Http404
doc = db[docid]
if filename not in doc['_attachments']:
  raise Http404
fileurl = urljoin('http://' + Site.objects.get_current().domain, docid, filename)
...
I could be wrong on determine server url, because I've never work with django, but idea is the same.
This approach should work if you have private CouchDB server that could be accessed from external.

Reply all
Reply to author
Forward
0 new messages