Skip to main content

Facebook open graph API client in python. Enables django applications to register users using facebook. Fixes issues with the official but unsupported Facebook python-sdk. Enables mobile facebook authentication. Canvas page authentication for facebook applications. FQL access via the server side api.

Project description

######################################################################
Django Facebook by Thierry Schellenbach (`mellowmorning.com <http://www.mellowmorning.com/>`_)
######################################################################

.. image:: https://secure.travis-ci.org/tschellenbach/Django-facebook.png?branch=master

.. image:: https://pypip.in/d/django-facebook/badge.png
:target: https://pypi.python.org/pypi/django-facebook

Contributions are strongly appreciated. Seriously, give github a try, fork and get started :)

News
----
* Now with support for django custom user models
* Unfortunately django-registration doesn't support custom user models. I recommend you to use the provided registration flow or Userena.

Demo & About
------------

Django Facebook enables your users to easily register using the Facebook API.
It converts the Facebook user data and creates regular User and Profile objects.
This makes it easy to integrate with your existing Django application.

I've built it for my startup Fashiolista.com and it's currently used in production with thousands of signups per day.
For a demo of the signup flow have a look at Fashiolista's landing page (`fashiolista.com <http://www.fashiolista.com/intro_wide_minimal/>`_)

After registration Django Facebook gives you access to user's graph. Allowing for applications such as:

* Open graph/ Timeline functionality
* Seamless personalization
* Inviting friends
* Finding friends
* Posting to a users profile

Updates and tutorials can be found on my blog `mellowmorning <http://www.mellowmorning.com/>`_

Further demos and tutorials will soon be available on `django-facebook.com <http://www.django-facebook.com/>`_



Features
--------

* Access the Facebook API, from:
* Your website (Using javascript OAuth)
* Facebook canvas pages (For building facebook applications)
* Mobile (Or any other flow giving you a valid access token)
* Django User Registration (Convert Facebook user data into a user model)
* Store likes, friends and user data locally.
* Facebook FQL access
* OAuth 2.0 compliant
* Automated reauthentication (For expired tokens)
* Includes Open Facebook (stable and tested Python client to the graph API)


Installation
------------

Clone the source code or use ``pip install django_facebook``.


**Create a Facebook App**

You need a facebook app to use the open graph API and make the login process work.
If you don't have a facebook app, now is the time to create one.
You can create a facebook app at `this url <http://www.facebook.com/developers/createapp.php>`_.

Facebook authentication only works if the domain you are working on matches your app domain.
Be sure to configure the right app domain in your facebook application settings.

An example:

Your site is www.fashiolista.com, your app domain is set to fashiolista.com and you do your development at ``local.fashiolista.com``.
If you try to authenticate with Facebook from a different domain you will get an authentication error.

**Settings**

Define the following settings in your settings.py file:

::

FACEBOOK_APP_ID
FACEBOOK_APP_SECRET

**Url config, context processor, auth backend**

add django facebook to your installed apps::

'django_facebook',

Add this line to your context processors (``TEMPLATE_CONTEXT_PROCESSORS`` setting)::

'django_facebook.context_processors.facebook',
# and add request if you didn't do so already
'django.core.context_processors.request',

The full setting on a new django 1.5 app looks like this::

TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.core.context_processors.request',
'django.contrib.messages.context_processors.messages',
'django_facebook.context_processors.facebook',
)


Add this to your ``AUTHENTICATION_BACKENDS`` setting::

'django_facebook.auth_backends.FacebookBackend',

The full setting on a new django 1.5 app looks like this::

AUTHENTICATION_BACKENDS = (
'django_facebook.auth_backends.FacebookBackend',
'django.contrib.auth.backends.ModelBackend',
)


Now, add this line to your url config::

(r'^facebook/', include('django_facebook.urls')),
(r'^accounts/', include('django_facebook.auth_urls')), #Don't add this line if you use django registration or userena for registration and auth.


**Update your models**

The following step depends on your version of Django. Django versions before 1.5 need to use a custom profile model.
Whereas Django 1.5 and up can use a custom user model.

**Django 1.5**

If you don't already have a custom user model, simply uses the provided model by setting your AUTH_USER_MODEL to FacebookCustomUser::

AUTH_USER_MODEL = 'django_facebook.FacebookCustomUser'

Alternatively use the abstract model provided in django_facebook.models.FacebookProfileModel

**Django < 1.5**

If you don't already have a custom Profile model, simply uses the provided model by setting your AUTH_PROFILE_MODULE to FacebookProfile::

AUTH_PROFILE_MODULE = 'django_facebook.FacebookProfile'

Be sure to run manage.py syncdb after setting this up.

Otherwise Django Facebook provides an abstract model which you can inherit like this::

from django_facebook.models import FacebookProfileModel


class MyCustomProfile(FacebookProfileModel):
user = models.OneToOneField('auth.User')
....

from django.contrib.auth.models import User
from django.db.models.signals import post_save

#Make sure we create a MyCustomProfile when creating a User
def create_facebook_profile(sender, instance, created, **kwargs):
if created:
MyCustomProfile.objects.create(user=instance)

post_save.connect(create_facebook_profile, sender=User)

Don't forget to update your database using syncdb or south after this step.

Note: You need a profile model attached to every user model. For new accounts this will get created automatically, but you will need to migrate older accounts.

**Congratulations**

Right now you should have a working registration/connect/login in flow available at /facebook/example/!
Test if everything is working and ensure you didn't miss a step somewhere.
If you encounter any difficulties please open an issue.


**Customize and integrate into your site**

Now it's time to customize things a little.
For an example you can look at connect.html in the templates directory.

First load the css:

::

<link href="{{ STATIC_URL }}css/facebook.css" type="text/css" rel="stylesheet" media="all" />

Secondly load the javascript:

::

{% include 'django_facebook/_facebook_js.html' %}

If you encounter issues here you probably don't have django static files setup correctly.
Alternatively you might be missing the context processor.


Subsequently implement a form which calls Facebook via javascript.
Note that you can control which page to go to after connect using the next input field.

::

<form action="{% url 'facebook_connect' %}?facebook_login=1" method="post">
<a href="javascript:void(0);" style="font-size: 20px;" onclick="F.connect(this.parentNode);">Register, login or connect with facebook</a>
<input type="hidden" value="{{ request.path }}" name="next" />
<input type="hidden" value="{{ request.path }}" name="register_next" />
<input type="hidden" value="{{ request.path }}" name="error_next" />
{% csrf_token %}
</form>


Redirects
---------

For most applications you can simply use the next, register next and error next parameters to control the post registration flow.
The "next" parameter provides the default next page for login, connect, error or register actions. "register_next" and "error_next" allow you to customize the next page for those specific scenarios. This is usefull when you for instance want to show an introduction page to new users.

Flows

* Login (login_next, next, default)
* Connect (connect_next, next, default)
* Register (register_next, next, default)
* Error (error_next, next, default)

The default redirect is specified by the FACEBOOK_LOGIN_DEFAULT_REDIRECT setting.

If the default customizability isn't adequate for your needs you can also subclass the default registration backend.

::

class CustomBackend(FacebookRegistrationBackend):
def post_connect(action):
# go as crazy as you want, just be sure to return a response
response = HttpRedirect('/something/')
if action is CONNECT_ACTIONS.LOGIN:
response = HttpRedirect('/')
return response

Canvas Application
------------------

In order to use build a facebook canvas application, you should add this to your ``MIDDLEWARE_CLASSES`` setting::

'django_facebook.middleware.FacebookCanvasMiddleWare'

This middleware will check for the signed_request parameter in the url and take the appropriate action:
* redirect to app authorization dialog if user has not authorized the app, some permission is missing or any other error.
* login the current facebook user in django's system and store the access token.

Common bugs
-----------

Django Facebook expects that you are using static files in order to load the required javascript.
If you are not using staticfiles you should load facebook.js provided in the static directory manually.

Another common issue are the url matching settings from Facebook. Facebook requires you to fill in a domain for your application.
In order for things to work with local development you need to use the same domain. So if you production site is www.mellowmorning.com you
should run your development server on something like local.mellowmorning.com in order for facebook to allow authentication.

If you encounter any difficulties please open an issue.


Registration Backends
---------------------

**Registration Backends**

By default Django Facebook ships with its own registration system.
It provides a basic manual registration flow and the option to connect with Facebook.

If you are looking for something more complicated it's possible to integrate with Userena or Django Registration.
To add support for these systems we use the FACEBOOK_REGISTRATION_BACKEND setting.


**Django Registration support**
Create a registration backend which subclasses both Django Facebook and Django Registration's
registration backend. An example is included in facebook_example/registration_backends.py

::
# in registration_backends.py
class DjangoRegistrationDefaultBackend(DefaultBackend, NooptRegistrationBackend):
'''
The redirect behaviour will still be controlled by the
post_error
post_connect
functions
the form and other settings will be taken from the default backend
'''
pass

# in your settings file
FACEBOOK_REGISTRATION_BACKEND = 'registration.backends.default.DefaultBackend'

**Django Userena support**

Django Userena is easier to work with than Django Registration.
It is however hard to setup unittesting with Userena, so the integration between Django Facebook and Userena might not work.
Please report any bugs you run into.

::

FACEBOOK_REGISTRATION_BACKEND = 'django_facebook.registration_backends.UserenaBackend'


Also have a look at the userena settings file in the facebook example project.
It provides a clear example of how to configure Userena and Django Facebook to work together.

**Other registration systems**

Supporting any other registration system is quite easy.
Adjust the above settings to point to your own code.
Note that the form's save method needs to return the new user object.


Signals
-------

Django-facebook ships with a few signals that you can use to easily accommodate Facebook related activities with your project.

``facebook_user_registered`` signal is sent whenever a new user is registered by Django-facebook, for example:

::

from django_facebook.utils import get_user_model
from django_facebook import signals

def fb_user_registered_handler(sender, user, facebook_data, \*\*kwargs):
# Do something involving user here

signals.facebook_user_registered.connect(user_registered, sender=get_user_model())


``facebook_pre_update`` signal is sent just before Django-facebook updates the profile model with Facebook data. If you want to manipulate Facebook or profile information before it gets saved, this is where you should do it. For example:

::

from django_facebook import signals
from django_facebook.utils import get_user_model

def pre_facebook_update(sender, user, profile, facebook_data, \*\*kwargs):
profile.facebook_information_updated = datetime.datetime.now()
# Manipulate facebook_data here

signals.facebook_pre_update.connect(pre_facebook_update, sender=get_user_model())


``facebook_post_update`` signal is sent after Django-facebook finishes updating the profile model with Facebook data. You can perform other Facebook connect or registration related processing here.

::

from django_facebook import signals
from django_facebook.utils import get_user_model

def post_facebook_update(sender, user, profile, facebook_data, \*\*kwargs):
# Do other stuff

signals.facebook_post_update.connect(post_facebook_update, sender=get_user_model())

``facebook_post_store_friends`` signal is sent after Django-facebook finishes storing the user's friends.

::

from django_facebook import signals
from django_facebook.utils import get_user_model

def post_friends(sender, user, friends, current_friends, inserted_friends, \*\*kwargs):
# Do other stuff

facebook_post_store_friends.connect(post_friends, sender=get_user_model())

``facebook_post_store_likes`` signal is sent after Django-facebook finishes storing the user's likes. This is usefull if you want to customize what topics etc to follow.

::

from django_facebook import signals
from django_facebook.utils import get_user_model

def post_likes(sender, user, likes, current_likes, inserted_likes, \*\*kwargs):
# Do other stuff

facebook_post_store_likes.connect(post_likes, sender=get_user_model())


Celery, Performance and Optimization
------------------------------------

Facebook APIs can take quite some time to respond. It's very common that you will wait
between 1-3 seconds for a single API call. If you need multiple calls, pages can quickly become very sluggish.

The recommended solution is to use Celery. Celery is a task queueing system which allows you to
run the API requests outside of the request, response cycle.

Step 1 - Install Celery

Step 2 - Enable Tasks

::

# use celery for storing friends and likes
FACEBOOK_CELERY_STORE = True
# use celery for extending tokens
FACEBOOK_CELERY_TOKEN_EXTEND = True

When writing your own Facebook functionality you will see a big speedup by using
@facebook_required_lazy
instead of
@facebook_required


Contributing and Running tests
------------------------------
Tests are run from within the example project. You
can run them yourself as follows:

install from git

facebook_example/manage.py test django_facebook


**Vagrant**

A vagrant development setup is included in the GIT repo.
Assuming you have vagrant installed, simply type the following in your shell:

::

# First get a fresh Django-Facebook checkout
git clone git@github.com:tschellenbach/Django-facebook.git django-facebook

# Go to the directory:
cd django-facebook

# Currently Vagrant is only support on branch `five`, so until this has been merged you need to switch branches:
git checkout five

# Time to start Vagrant (grab a cup of coffee after this command, it'll take a while) :)
vagrant up

# Finally done?
vagrant ssh
python manage.py runserver 0:8080

To have a working Django Facebook example up and running at 192.168.50.42:8000/facebook/example/.
For the facebook login to work simply map that ip to vagrant.mellowmorning.com
(Since Facebook checks the domain)

You can run the test suite by typing:

::

python manage.py test django_facebook



Django Jobs
-----------
Do you also see the beauty in clean code? Are you experienced with high scalability web apps?
Currently we're looking for additional talent over at our Amsterdam office.
Feel free to drop me a line at my personal email for more information: thierryschellenbach[at]gmail.com

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-facebook-5.2.10.zip (308.8 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page