Chatrooms is an app that provides multi-user chat rooms for your django site.
It's completely based on jQuery and gevent, whose libraries have been used to implement long polling.
It provides a set of models, views and templates ready out of the box and easily customizable.
Install the egg from pypi:
$ pip install django-chatrooms
or get the latest revision from github:
$ pip install -e git+git://github.com/qubird/django-chatrooms#egg=chatrooms
If you use buildout, just add
django-chatrooms to your eggs part.
Once the egg is installed, add the following apps to your settings.INSTALLED_APPS:
INSTALLED_APPS = ( # ..., 'polymorphic', 'chatrooms', # ..., )
Then include chatrooms urls to your urlpatterns:
urlpatterns = patterns('', # ..., url(r'^chat/', include('chatrooms.urls')), # ..., )
Make sure you also added
staticfiles_urlpatterns to urlconf like:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns urlpatterns += staticfiles_urlpatterns()
'django.contrib.staticfiles' is amongst
Then you're ready to run
To use the app with servers that pre-fork the application before running, like gunicorn does, you need to use some sort of interprocess communication.
chatrooms.utils.redis_handlers module contains the
which can be set as
settings.CHATROOMS_MESSAGE_HANDLERS to use the application
in a gunicorn-like environment.
The module needs a redis instance installed and running to work.
chatrooms.utils.celery_handlers.CeleryMessageHandler class has been included.
It can be used as
settings.CHATROOMS_MESSAGE_HANDLERS as well, but needs celery to be installed.
See the Message Handlers section to know how to implement your own handlers.
Using the app
The app installs two models: Room and Message. Rooms can be created by Admin Site. Room objects have the following fields:
|slug:||which identifies the room in urls and views|
|subscribers:||which references a set of users (not used by default)|
|allow_anonymous_access:||which tells whether the room is accessible only to logged users, or event to "guests". A guest user is asked to choose a guest name before entering the room.|
|password:||These fields aren't used by default. They might be useful for implementing custom policies of access. See the Custom access policies section for further details.|
Besides the core views that handle ajax requests to make the chat work, some class-based views have been designed.
These are in
RoomsListView, which shows the list of rooms filtering the ones requiring a logged user if the user is not authenticated
RoomView, which renders the actual room page
GuestNameView, which is shown to non-logged users entering an
allow_anonymous_accessroom to choose a guest name
The templates you might want to override are
chatrooms/guestname_form.html, which is rendered by GuestNameView: it shows the form for choosing a guest name
chatrooms/rooms_list.html, which is rendered by RoomsListView
chatrooms/room.html, which is the skeleton of the page where chat objects are placed dynamically. The page includes the
js/room.jsscript which requires a
Some elements are required by
room.js and need to be included in
#chatText: an empty
#chatSendText: text input where the user enters the text to send,
#chatSendButton: button input pressed by user to submit text,
#connectedUsersList: a list element where connected users are shown.
static/css folder contains the file
room.css you might want to override to re-style the room page.
test_gevent command has been implemented to test the chat features that use gevent libraries.
utils.handlers.MessageHandler class implements the methods
handle_received_message(sender, room_id, username, message, date, [user])
sender: the ChatView instance room_id: the id of the room where the message was sent username: username or guest name of the user who sent the message message: the content of the sent message date: the timestamp of the sent message user: request.user if user is authenticated, else
retrieve_messages(chatobj, room_id, latest_msg_id)
chatobj: the ChatView instance room_id: the id of the room whose messages are requested latest_msg_id: the id of the latest message sent to the room
chatobj: the ChatView instance room_id: the id of the room whose latest message id is requested
handle_received_message method is designed to perform operations
with the received message such that
retrieve_messages is able to
retrieve it afterwards.
retrieve_messages must return a list of tuples like
[(message_id, message_obj), ...], where
message_obj is an instance of
Message or an object with at least the following attributes:
message_id is a unique progressive identifier.
get_latest_message_id must give back the id of the latest message received,
consistently to the ways messages are stored and retrieved.
To implement your handlers you need to create a class extending
override the aforementioned methods, and add to your settings:
CHATROOMS_HANDLERS_CLASS = 'my.app.MyHandlerClass'
This way your defined methods will be used as default handlers for received messages and requests for messages.
ajax.chat.ChatView docstrings for further details on these classes.
Custom access policies
Access to rooms can be controlled defining a function which takes
user as arguments, and returns True or False whether the user is allowed to access the room or not (
room_id is given as a GET parameter of the request).
Once you defined your function, say
my.app.user_can_enter_foo, add to your settings:
CHATROOMS_TEST_USER_FUNCTION = 'my.app.user_can_enter_foo'
Your function will be used as a test by view decorators.
When the user sends ajax requests to send or get chat messages, or get the connected users list,
user are passed to your function.
If it returns
False, a 403 Forbidden Resource response is given, else the request is normally processed.
Denis Bilenko 's webchat example has been a great starting point for the design of this app.
- Users list methods could be improved to work properly in multi-process environments, as it's been done with message handlers.