Archive for the ‘django’ tag
S-I-P goes online
In an earlier post, I mentioned about developing a photo-blog in Django. I’m happy to announce that over the last week, I hosted in WebFaction and it is online now.
I realized that hosting Django applications are not that easy – WordPress installation is easy – transfer files; setup some parameters and in about 5 minutes you are up and ready to go. That is the case even for a newbie. However it took me about a week to get this first installation up and running. I was even close to giving up out of frustration.
Good news is that I didn’t give up.
Surely WebFaction, has made Django hosting easier. They have a single-click install of Django – be it with mod_python or with mod_wsgi. You can even choose the trunk version or the official release. Without these it would’ve been a nightmare for newbie like me to host Django applications.
My learning on Django hosting will be another post. This one is about the photo-blog.
As the images are hosted in Flickr, first step is to add Flickr API Key.
Then you start to add photos by providing the Flickr Photo id:
I’m using Beej’s Flickr Python API to connect to Flickr and get information. With the photo id, it will get the EXIF information, photo title, description and tags and store it locally. Once the information is obtained, if needed, it can be changed as well. If the information has to be obtained from Flickr again, just delete the title and it will fire the query again.
That’s all to be done to add a photo!
Coming to the homepage, I’ve designed a very simple homepage. (It shows up messed up in IE; it is ok in Firefox). Most of the part works – browse via tags, comments, about page etc. In the days to come, I want to incorporate the below features:
- Tags as a drop down in browse page
- Email notification of comments
- Comments moderation
- Caching
- Contact form
At this moment, I’m not interested in voting or favorites. But might consider these as add-on features at a later time.
As always the code is hosted in Google hosting. Feel free to browse, comment, code review.
Understanding Django Template Tags
A photoblog is incomplete if there is no provision to display information, like EXIF, about the photo. For S-I-P, I need to pass these information to the templates. But what is a better way to do it? Variables can be passed via view functions and I’ve already done that. Per Django documentation, something similar can be achieved via Template Tags too.
Okay now I’m confused. Should I use view function or template tags? If I could use view function to achieve the same, what is the need for template tags. I read and re-read, the otherwise excellent, Django documentation and Django Book. I couldn’t get a clarification.
Then I stumbled on James Bennet‘s article on Template tags. He makes it clear:
If you want to have, say, a list of recently-added content which appears in a sidebar or footer on every page of a site, it’d be crazy to manually change every view to fetch that content and add it to the template context; a template tag is definitely the way to go.
Let me re-word it: Let us say you want to display site name in all pages. Depending on the urls, you may have more than one view function. If so, then site name has to be included in all the context variable of each view function. Template Tags come to the rescue here. You can define a template tag and then it can be invoked from all the templates.
So here is how I implemented displaying site name in all templates.
First define the site name in settings.py; well ideally it should be defined in a db table. But I just starting with S-I-P. As I go along, I will change that.
SITE_NAME = 'Say In Pixels'
As per the above documentation that I referred, the templatetags should reside within the application (on the same level as models.py). So create a directory called templatetags and create a __init.py__ and another file which will contain the tags. The name of the file is important as it will invoked from templates. In my case I named it as sip_tags.py. Here is my directory structure.
sip/
models.py
views.py
templatetags/
__init.py__
sip_tags.py
As of now, sip_tags.py contains just one tag – one to return the site name that was defined in settings.py.
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def site_name():
return settings.SITE_NAME
Now this has to be invoked from the templates. Here is how the html template looks like:
{% load sip_tags %}{% block site_info %} <h1><a href="/">{% site_name %}</a></h1>{% endblock site_info %}
Note that sip_tags were loaded at the beginning of the template. site_name is available for all the templates and view functions can just handle the business logic.
(Thanks to the soul who is known as mkes in the #django IRC channel. I was using {{ site_name }} and wondering why the hell it wasn’t appearing the output. He clarified it. That is the power of Django Community! One another reason why I like to program in Django)
References:
The Django template language: For Python programmers
Say In Pixels – a photoblog in Django
I love to take photos. And show off!
The problem is I don’t take good photos. To take good photos, I need to take lots of photos. I will take lots of photos, if I can show off. To show off, I need an easy to use application which fits my bill. See my problem?
To host a photoblog, one needs enormous disk space which demands enormous money.
Okay there is Flickr (leaving aside Microsoft’s attempt to mess it up). But Flickr allows only members to comment. And it is not well suited as a photoblog.
So I decided to write a photoblog on my own. It is easier to code it on my own rather than complaining about all the existing ones. (May be someone else will complain about mine. But then, that would indicate that mine became popular!)
So here are the feature list that my photoblog will have:
- Will be Django based – Cool way to learn Django. If I can’t use technology to solve my problem, how can I use it to solve other’s problems.
- Flickr Integration – I’ll keep Flickr as primary storage.
- Tagging – Categories are one dimensional. Lets get away from it. Read more at Organize Pictures. How cool it would be if EXIF data also is used as tags?
- All other generic blog features – like comments, archives and the rest.
- PixelPost in Django? – # 1 photoblog application. But that is in PHP. Can I match it in features – especially easy to install? – and in popularity?
- Hosted in Google – Where else?
Am sure to pull through s-i-p. Only time will tell if I become a better photographer.
A free (but superb) Django hosting
Ever since I stared to learn Django, I’ve looking for a web-host to host the apps that I develop – so that I can learn the every bit of the learning chain: from design until hosting. As it was for learning purpose, I didn’t want to pay heavily for it. So primarily I was looking for some free hosting service.
I came to know via Django Google Groups that bells-n-whistles provide a fee hosting service. I sent them a mail via their contact form. They setup the free domain and sent me a mail regarding the details. Their free hosting access is only via FTP.
I had starting glitches with the hosting. Every time I sent them a mail, they were very prompt in answering back. Being a newbie into Django (especially its hosting), I probably asked silly and annoying questions. Not minding, they replied back with answers – simple yet to the point.
There is no detailed documentation on their site. So here is what worked for me.
Here is the snippet of settings.py
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = os.path.join(PROJECT_DIR, 'sol.db')
MEDIA_ROOT = '%s' % PROJECT_DIR
MEDIA_URL = 'media/'
ADMIN_MEDIA_PREFIX = '/media/'
TEMPLATE_DIRS = (
r'%s/templates/sol' % PROJECT_DIR,
r'%s/templates' % PROJECT_DIR,
r'%s/templates/admin' % PROJECT_DIR,
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.admin',
'sol',
)
As you can see, I am using sqlite instead of their default db PostgreSQL. As it is a demo db, it works okay for me.
Then transfer both application templates and admin templates to templates directory. Transfer css files to media directory. If you have file uploads (like images or avatars), they should be within media directory as well.
Of course since it is a free hosting, you need to add a link to their site. For the free service that they provide, it is expected. If I continue to learn Django (I’ll be), then I will most probably, go with them for hosting.
You can visit their site at: bells-n-whistles. The one that I’m hosting is at: http://cephire.bells-n-whistles.net. (Since it is a demo and just setup, there is not much there. Hope to add over the time. It is a Twitter clone. If you want to try it out, use jjude/jjude for user id/password).
Adding RSS feeds to Django Applications
Being a relatively ‘young’ framework, most of the requirements for building social applications works right out-of-the-box from Django. One such feature is ‘feeds’. Here is how I built ‘feeds’ for SOL.
URLs
I followed the convention and url for the feeds are in ‘/feeds/’. Make the below changes to urls.py.
(r'^feeds/(?P<url>.*)/$', 'feed', {'feed_dict': {
'latest': LatestSOLs,
'user': UserSOLs,
'group': GroupSOLs}
}
),
)
What this means is that, there are three feeds available – one of the latest entries, one for the user entries and another for the group. The corresponding functions should be in feeds.py.
Feeds
The easiest one is to create feed for all the entries: just derive from Feed class; define title, link and description for the feed; return the entries. Django does the rest of the stuff.
title = '%s : Latest SOLs' % settings.SITE_NAME
link = '/'
description = 'Latest entries to %s' % settings.SITE_NAME
def items(self):
return sol.objects.order_by('-date')[:settings.FEED_SIZE]
It gets little complex when parameters are passed via URL, user id or group id, and feed should be built accordingly. You need to find the object (user or group) and filter accordingly.
title_template = 'feeds/title.html'
description_template = 'feeds/description.html'
def get_object(self, bits):
if len(bits) < 1:
raise ObjectDoesNotExist
return userprofile.objects.get(user__username__exact=bits[0])
def title(self, obj):
return "SOLs of '%s'" % obj.nickname
def link(self, obj):
return "/"
def description(self, obj):
return "SOLs recently posted by %s" % obj.nickname
def items(self, obj):
return sol.objects.filter(author__username=obj.user.username).order_by('-date')[:settings.FEED_SIZE]
Templates
You need to design a template for title and description of the feeds. They are pretty simple.
title.html
It can be as simple as {{ obj.title }}
description.html
Feeds are ready. They need to be included in the home page templates so that browsers can identify them.
For all entries:
<link rel="alternate" type="application/rss+xml" title="Public Feeds" href="/feeds/latest/">
{%endblock feeds%}
For feeds specific to a user:
<link rel="alternate" type="application/rss+xml" title="User Feeds" href="/feeds/user/{{u_id}}" />
{%endblock feeds%}
That’s all needed to enable feeds for your social application.
You can browse the code from google hosting.
References
http://www.djangoproject.com/documentation/syndication_feeds/
http://www.andrlik.org/blog/2007/aug/03/fun-with-django-feeds/
del.icio.us Tags: django,rss,syndication
Technorati Tags: django,rss,syndication