Django best practices III: Install South, Localization, Internationalization and Django-registration

This is the third post about I write about how to build a Django project from scratch, focusing on the project structure, internationalization and localization configuration, models, managers, views, forms and templates. Take a look at Part I and Part II here.

In this post, I write about how to install South, how to prepare your project for internationalization and localization, and how to install and use the package django-registration to manage the registration and login of users.

Install South

South is a very useful Django package that manages changes in your models and database. To install it, activate your virtual environment and type:

$ pip install South

You should include the installed version of South in your requirements.txt file. If you followed this tutorial from Part I, you should have created a common.txt file with the common requirements of the development, production and testing environments. Type

$ pip freeze

to see which version of South you have installed, and add that line into your common.txt file (for me it was South==0.8.4). If you only have one requirements.txt file, you can type directly

$ pip freeze > requirements.txt

to save all the dependencies needed to a single file.

On your settings.py add:

INSTALLED_APPS = (
    …
    ‘south’,
    …
)

As we don’t have any app created, we can sync the database to see if South is installed properly. If on the contrary, you have created an app, and you want it to be managed by South, don’t do this step yet.

$ python manage.py syncdb

Settings configuration for Localization and Internationalization

Another thing you might need is to prepare your app to support different languages. First, create a folder named locale at the same level of your settings.py file.

$ mkdir locale

Open your settings.py file and make sure you have the internationalization flag set to true: USE_I18N = True. Then, add the following at the bottom (change your languages accordingly):

ugettext = lambda s : s
LANGUAGES = (
    (‘en’, ugettext(‘English’)),
    (‘ca’, ugettext(‘Catalan’)),
)
LOCALE_PATHS = os.path.join(BASE_DIR, ‘locale’)

 

And finally, add the locale middleware in the correct position:

MIDDLEWARE_CLASSES = (
    …
    ‘django.contrib.sessions.middleware.SessionMiddleware’,
    ‘django.middleware.locale.LocaleMiddleware’,
    ‘django.middleware.common.CommonMiddleware’,
    …
)

These are the first steps for preparing your app to allow different languages. Later on we will discuss the next steps.

You might also want to change the variable TIME_ZONE in your settings.py file to your local time zone. In my case, that was

TIME_ZONE = ‘Europe/Madrid’

This is very important if you want to use Localization on your project.

Django-registration

The package django-registration is a very useful package that manages registration of new users. It also allows to send an email to activate accounts, and provides other functionalities like the change of password or recovery of an account. Unfortunately, it is no longer maintained 🙁 A good option is try with django-allauth — I’ll try it myself and make a post when possible 😉

If you still want to use it, specially if you are working with Django < 1.5 or you’re not using custom User models, I’ll show you how.

To install it, activate your virtual environment and type

$ pip install django-registration

and insert this package in your requirements.txt file. If you followed this tutorial from the beginning, type pip freeze to see which version has been installed and insert it manually in your common.txt requirements file.

Next, add this app in your settings.py file:

INSTALLED_APPS = (
    …
    ‘registration’,
    …
)

 

You need an active email from which to send the emails. At the end of the settings.py file add the details of this email (this example is done with a gmail account):

EMAIL_USE_TLS = True

EMAIL_HOST = ‘smtp.gmail.com’

EMAIL_HOST_USER = ‘your.email@gmail.com’

EMAIL_HOST_PASSWORD = ‘your.password’

EMAIL_PORT = 587

And also add a line to limit the number of days to activate the account:

ACCOUNT_ACTIVATION_DAYS = 7

Before proceeding we need to sync the django-registration models into the database:

$ python manage.py syncdb

Next, open the main urls.py file and include the urls for this new application:

urlpatterns = patterns(”,
    …
    url(r‘^accounts/’, include(‘registration.backends.default.urls’)),
    …
)


If you read the docs of this package, you will see that it calls several templates that must be in a folder called registration. You can create each template yourself, or you can download a simple version of them from GitHub. I’d take the second option 🙂

Download the registration folder from GitHub and place it in your mytemplates/templates folder. As you can see, each template inherits from your base.html template and the content is placed with a block tag. If you followed this tutorial from the beginning, Django will automatically render this templates.

There is a thing you might want to change: when you log in, django will automatically redirect you to the url “accounts/profile”, which is the default url when the contrib.auth.login view gets no next parameter. To change the default url, include this line in your settings.py file:

LOGIN_REDIRECT_URL = ‘/’

this way, after loggin in, the user will get redirected to your home page (you can change the url to whichever page you want to redirect the user). 

However, if you use Django 1.6 you will find several problems when your try to reset or change the password. You will find a temporal solution in this post. Basically, you need to override some urls and use the Django admin interface to deal with password changes.

Hope it was useful! Next port is available here:

Django best practices IV: Models, forms, managers, urls, admin, views and signals

Please, give a +1 if you liked it!! 🙂

Google+TwitterLinkedInFacebookReddit

Please, add +Marina Mele in your comments. This way I will get a notification email and I will answer you as soon as possible! :-)