Notes

Retrieve and display facebook albums using FQL and Django

Posted by Dan on Sunday the 11th of September, 2011

Here is a useful little Django app that I have created to get and display albums and pictures from a facebook 'page' using Facebook Query Language (FQL). You can get the app django-fbgallery from Github and view a demo of it here.

Setup

To set up the app you first need to get the facebook id from the 'Page' that you want to retrieve the albums from, you can do this by looking at the URL on facebook, for example: http://www.facebook.com/media/albums/?id=6798562721 on the album page it's just the id part of the URL. If you look at the URL from a photo from the album: http://www.facebook.com/photo.php?fbid=10150265446187722&set;=a.436358817721.235581.6798562721 it's the code at the end.

Then in your settings file you can add the ID of the facebook album you want to list, also make sure to include the app in installed apps.

1
2
3
4
5
6
#settings.py
FB_PAGE_ID = '6798562721'

INSTALLED_APPS = (
        'fbgallery',
)

In your urls file you need to include the apps url file like so:

1
2
3
4
#urls.py
urlpatterns += patterns('',
    (r'^gallery/', include('fbgallery.urls')),              
)

How it works

The main function takes a FQL query and returns the results as JSON, the results are also cached for each separate query to prevent too many requests to facebook.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def get_fql_result(fql):
    cachename = 'fbgallery_cache_' + defaultfilters.slugify(fql)
    data = None
    if cache_expires > 0:
        data = cache.get(cachename)
    if data == None: 
        options ={
            'query':fql,
            'format':'json',
        }
        f = urllib2.urlopen(urllib2.Request(fql_url, urllib.urlencode(options)))
        response = f.read()
        f.close()
        data = json.loads(response)
        if cache_expires > 0:
            cache.set(cachename, data, cache_expires*60)
    return data

The albums are retrieved from the facebook id, a separate query is made to get each album cover as I don't think FQL supports joins.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def display_albums(request, fb_id):
    """ Fetch all facebook albums for specified id """
    fql = "select aid, cover_pid, name from album where owner=%s" % fb_id;
    albums = get_fql_result(fql)
    for i in range(len(albums)):
        fql = "select src from photo where pid = '%s'" % albums[i]['cover_pid'];
        [item for sublist in get_fql_result(fql) for item in sublist]
        albums[i]['src'] = sublist['src']
          
    data = RequestContext(request, {
        'albums':albums,
        })
    
    return render_to_response('fbgallery/albums.html', context_instance=data)

To display all pictures from an album the album id is passed in through the URL and then checked to see if it belongs to the facebook page specified.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def display_album(request, album_id, fb_id):
    """ Display a facebook album, first check that the album id belongs to the page id specified """
    fql = "select aid, name from album where owner=%s and aid='%s'" % (fb_id, album_id)
    valid_album = get_fql_result(fql)
    if valid_album:
        fql = "select pid, src, src_small, src_big, caption from photo where aid = '%s'  order by created desc" % album_id
        album = get_fql_result(fql)
        [item for album_detail in valid_album for item in album_detail]       
    else:
        raise Http404
    
    data = RequestContext(request, {
        'album':album,
        'album_detail':album_detail,
        })
    return render_to_response('fbgallery/album.html', context_instance=data)