Bixly How-To: integrate django with facebook – part1
**This article refers to an older version of the Facebook developers page and api, and may have changed since the writing** Being the biggest social...
In the previous entry, “Bixly How-To: integrate django with facebook – part1”, we used the Facebook Javascript SDK to provide access to the Graph API for the user. The Facebook Graph API accessed with the Python SDK and Javascript SDK provides a lot of operations with regards to accessing user information (e.g. …
In the previous entry, “Bixly How-To: integrate django with facebook – part1”, we used the Facebook Javascript SDK to provide access to the Graph API for the user.
The Facebook Graph API accessed with the Python SDK and Javascript SDK provides a lot of operations with regards to accessing user information (e.g. access token, friends, news feed) and other tasks such as album creation and image upload. We will continue where we left off in part 1 of this 2-part tutorial. We encourage you to integrate Facebook’s Javascript SDK shown in part 1 first before proceeding below.
Including the Facebook’s Python SDK
Step 1: We first create a folder in the app folder called fbconnect. Download facebook.py from (link no longer exists) and store it in the fbconnect folder. We rename it to fbconnect.py for convenience. We need to create an empty __init__.py in the same directory so that django defines the folder as a package.
Step 2: We then create a file named fbutils.py in the same folder containing the code below.
import fbconnect from settings import FB_APP_ID, FB_APP_SECRET appid = FB_APP_ID appsecret = FB_APP_SECRET def connect(request): user = fbconnect.get_user_from_cookie( request.COOKIES, appid, appsecret) if user: fbgraph = fbconnect.GraphAPI( user["access_token"]) return fbgraph, user["access_token"] return None, None
This code simply wraps fbconnect’s function get_user_from_cookie. If the user is logged in through Facebook, the get_user_from_cookie function returns a dictionary containing ’uid’ which is the user’s Facebook ID and ‘access_token’ which can be used to make authenticated requests to Facebook’s Graph API. When we call the connect function we created above, we’ll receive either the Facebook GraphAPI instance and the user access token when the user is logged in via Facebook or None, None otherwise.
When we have the user’s access token, we can easily perform Facebook API calls such as accessing the user’s information, image uploading, posting content in user’s walls, and creating and modifying events (provided that the user granted such permissions for the application).
Step 3: We modify the views.py code to have
def index(request): fbgraph,access_token = connect(request) context = { 'access_token':access_token, } return render_to_response('index.html', context, context_instance=RequestContext(request))
Given that the connect function returns fbgraph object and the access token, we first include in the view the value of the Facebook access token of the user.
We then display the access_token value after “Updated Time” in your template page.
<div id="other_information" style="display: none;"> ... Updated Time: <span id="updated_time"></span><br /> Access Token: </div>
Step 4: The Graph API of Facebook can also be accessed using the Python SDK provided. In our case, all we need to do is to use the fbgraph object provided by our connect function.
By using the python code fbgraph.get_object(‘me’), we get the same values as the javascript code FB.api(‘/me’). Notice that the only difference between them is syntax.They both access https://graph.facebook.com/me with the access token as the parameter. If you want to see the keys and values returned by the Graph API, view this in your web browser https://graph.facebook.com/me?access_token=ACCESS_TOKEN.
Include the fbgraph.get_object(‘me’) codes in your views.py. It should look something like this.
def index(request): fbgraph,access_token = connect(request) fbgraph_me = fbgraph.get_object('me') context = { 'access_token':access_token, 'fbgraph_me':fbgraph_me } return render_to_response('index.html', context, context_instance=RequestContext(request))
To see the dictionary value of the fbgraph_me variable we passed to the template, we add this line after the access token in index.html
FBGraph Me: <pre></pre>
Step 5: The Graph API also has the capability to display the user’s friends. To demonstrate this, we use fbgraph.get_connections(‘me’,’friends’) to get the list of friends of the user. The python code fbgraph.get_connections(‘me’,’friends’) returns a dictionary of the form
{u'data': [{ u'name': u'Friend1Name', u'id': u'Friend1ID'}, {u'name': u'Friend2Name', u'id': u'Friend2ID'} ]}
We then include fbgraph_friends = fbgraph.get_connections(“me”, “friends”)[‘data’] in our views.py and we add the following code in our template page.
FBGraph Friends:<br />
Step 6: We can also get the user’s news feed with the Graph API. By using fbgraph_newsfeed = fbgraph.get_connections(“me”, “home”), we get to a dictionary of the form
{ u'paging': { u'next': <next value>, u'previous': <previous value> }, u'data': [ { u'from': <from dictionary>, u'privacy': <privacy dictionary>, u'actions': [ { u'link': <action link>, u'name': <action name> }, { u'link': <post link>, u'name': <action name> } ], u'updated_time': <updated time>, u'created_time': <created time>, u'message': <message>, u'type': <status>, u'id': <post id> }, { u'from': <from dictionary>, u'privacy': <privacy dictionary>, u'actions': [ { u'link': <action link>, u'name': <action name> }, { u'link': <post link>, u'name': <action name> } ], u'updated_time': <updated time>, u'created_time': <created time>, u'message': <message>, u'type': <status>, u'id': <post id> }, ] }
where each dictionary stored in the data list refers to one post in the user’s wall.
To display the posts in the user’s wall, we include fbgraph_newsfeed = fbgraph.get_connections(“me”, “home”)[‘data’] in our views.py and we then add the following code to our template page.
<br />FBGraph News Feed:<br />
Step 7: Sometimes, obtaining the user’s photos is needed in the web application. This is also possible through Facebook’s Graph API. First we create a wrapper function in fbutils.py for the function fbgraph.request(‘me/albums’,args={‘access_token’:fb_access_token}) which returns a dictionary of data from Facebook. The wrapper function for obtaining the photo albums of the user will simply return a list containing an album’s name and id. The wrapper function is provided below.
def getAlbums(fbgraph,fb_access_token): response = fbgraph.request('me/albums', args={'access_token':fb_access_token}) data = response['data'] album_list = [] for album in data: album_list.append({ 'id':album['id'], 'name':album['name']}) return album_list
The wrapper function above returns a dictionary with the form
[ { 'id': , 'name': }, { 'id': , 'name': }, ]
Now we add the following lines of code in views.py to print the ids and names of each album of the user on the console.
fbgraph_albums = getAlbums(fbgraph, access_token) for fbgraph_album in fbgraph_albums: print fbgraph_album['id'], fbgraph_album['name']
Given the ID of an album, using the GraphAPI, we can get the information of all the images in the specified album. We create another wrapper function in fbutils.py for the function fbgraph.request(‘%s/photos’%album_id,args={‘access_token’:fb_access_token}) which returns a dictionary of data from Facebook. The wrapper function for obtaining the photos of the album of the user will simply return a list containing urls of each image. The wrapper function is provided below.
def getPhotos(fbgraph,fb_access_token,album_id): response = fbgraph.request('%s/photos'%album_id, args={'access_token':fb_access_token}) imagecollection = [] for photo in response['data']: imagecollection.append(photo['picture']) return imagecollection
To test the wrapper function above, we modify views.py and include the code below.
for fbgraph_album in fbgraph_albums: print fbgraph_album['id'], fbgraph_album['name'] print getPhotos(fbgraph, access_token, fbgraph_album['id'])
The console should then have something like
<album 1 id>: <album 1 name> [<url to photo 1 of album 1>, <url to photo 2 of album 1>, ...] <album 2 id>: <album 2 name> [<url to photo 1 of album 2>, <url to photo 2 of album 2>, ...]
To display all the photos in each album of the user, we modify views.py again to contain the code below.
fbgraph_photos = [] for fbgraph_album in fbgraph_albums: fbgraph_photo_album_name = fbgraph_album['name'] fbgraph_photo_album_photos = getPhotos(fbgraph, access_token, fbgraph_album['id']) fbgraph_photos.append({ 'album_name': fbgraph_photo_album_name, 'album_photos': fbgraph_photo_album_photos})
We also include the following code in the template page as well:
<br />FBGraph Photo Albums:<br />
The code above simply displays all the images inside the album successively. Clicking on the images will open a new page containing the original Facebook photo.
Step 8: Access to the Graph API for each user depends on the permissions allowed for the application. It is advisable to check the allowed permissions for the app before trying to gain access to any specific user information or action. This is possible through fbgraph.get_connections(‘me’,”permissions”) which returns a dictionary of the form:
{'data':[{ 'read_stream': 1, 'user_birthday': 1, ... 'friends_status': 1, }]}
The dictionary returned by Facebook contains only the keys of the allowed permissions. To check if a permission has been allowed for a specific request, we may do the following:
fbgraph_permissions = fbgraph.get_connections('me',"permissions")['data'] if key in fbgraph_permissions: #do something
Notes: There is a lot more to Facebook Graph API and Facebook Python SDK than what I have described here. Be sure to check out the documentation for all the rest of the features. For reference purposes, the codes are shown below.
#views.py from django.shortcuts import render_to_response from django.template import RequestContext from fbconnect.fbutils import connect, getAlbums, getPhotos def index(request): fbgraph,access_token = connect(request) if fbgraph: fbgraph_me = fbgraph.get_object('me') fbgraph_friends = fbgraph.get_connections( "me", "friends")['data'] fbgraph_newsfeed = fbgraph.get_connections( "me", "home")['data'] fbgraph_albums = getAlbums( fbgraph,access_token) fbgraph_photos = [] for fbgraph_album in fbgraph_albums: fbgraph_photo_album_name = fbgraph_album['name'] fbgraph_photo_album_photos = getPhotos( fbgraph, access_token, fbgraph_album['id']) fbgraph_photos.append({ 'album_name': fbgraph_photo_album_name, 'album_photos': fbgraph_photo_album_photos}) fbgraph_permissions = fbgraph.get_connections( 'me',"permissions")['data'] context = { 'access_token':access_token, 'fbgraph_me':fbgraph_me, 'fbgraph_friends':fbgraph_friends, 'fbgraph_newsfeed':fbgraph_newsfeed, 'fbgraph_photos':fbgraph_photos, 'fbgraph_permissions': fbgraph_permissions, } else: context = { } return render_to_response('index.html', context, context_instance=RequestContext(request))
#index.html <html> <head> <!-- JS Files --> <script type="text/javascript" src="js/jquery.js"></script> <!-- Document Ready functions --> <script type="text/javascript"> //functions which are done when the document is ready $(function(){ fbconnected(function(){ // connected to facebook fblogin_success(); },function(){ // not connected to facebook fblogin(fblogin_success,fblogin_fail); }); }); </script> <script type="text/javascript"> function fblogin_success(){ //logged in user FB.api('/me', function(response) { $('#name').html(response.name); $('#first_name').html(response.first_name); $('#last_name').html(response.last_name); $('#link').html(response.link); $('#birthday').html(response.birthday); $('#gender').html(response.gender); $('#timezone').html(response.timezone); $('#locale').html(response.locale); $('#verified').html(''+response.verified); $('#updated_time').html(response.updated_time); $('#other_information').show(); }); $('#post_button').click(function(){ var body = $('#post_box').val(); FB.api('/me/feed', 'post', { message: body }, function(response) { if (!response || response.error) { alert('Your post was not published successfully'); } else { alert('Your post "'+body+'" was published successfully'); } }); }); $('#post_div').show(); } function fblogin_fail(){ //guest } </script> </head> <body> <div id="post_div" style="display:none"> Post something in your wall! <br /> <input id="post_box"/><button id="post_button">Submit</button> </div><br /> <div>Hello <span id="name">Guest</span>!<br /> <div id="other_information" style="display: none;"> First Name: <span id="first_name"></span><br /> Last Name: <span id="last_name"></span><br /> Link: <span id="link"></span><br /> Birthday: <span id="birthday"></span><br /> Gender: <span id="gender"></span><br /> Timezone: <span id="timezone"></span><br /> Locale: <span id="locale"></span><br /> Verified: <span id="verified"></span><br /> Updated Time: <span id="updated_time"></span><br /> Access Token: <br /> FBGraph Me: <pre></pre><br /> <br />FBGraph Friends:<br /> <br />FBGraph News Feed:<br /> <br />FBGraph Photo Albums:<br /> <br /> FBGraph Permissions: <pre></pre> </div> </div> </body> </html>
#fbutils.py import fbconnect from settings import FB_APP_ID, FB_APP_SECRET appid = FB_APP_ID appsecret = FB_APP_SECRET def connect(request): user = fbconnect.get_user_from_cookie( request.COOKIES, appid, appsecret) if user: fbgraph = fbconnect.GraphAPI( user["access_token"]) return fbgraph, user["access_token"] return None, None def getAlbums(fbgraph,fb_access_token): response = fbgraph.request('me/albums', args={'access_token':fb_access_token}) data = response['data'] album_list = [] for album in data: album_list.append({ 'id':album['id'], 'name':album['name']}) return album_list def getPhotos(fbgraph,fb_access_token,album_id): response = fbgraph.request('%s/photos'%album_id, args={'access_token':fb_access_token}) imagecollection = [] for photo in response['data']: imagecollection.append(photo['picture']) return imagecollection
References:
**This article refers to an older version of the Facebook developers page and api, and may have changed since the writing** Being the biggest social...
TinyMCE is a JavaScript WYSIWYG editor that converts an HTML textarea field into an editor instance. django-tinymce is a Django application that...
Reducing css and javascript page load size is integral to web development. Minimization will reduce web page size as well as the overhead cost of...