Extend Django User Model

Django CMS has its own User model but you might need to add attributes and other properties to it (like an avatar, right ?). The easiest way to do that is to extend that model with another model (we’ll call it UserProfile) and link them together using a one-to-one relationship.

Creating the UserProfile model

Nothing special here, I’m sure you know how it works.

Creating a UserProfile when creating a User

Each User needs to have a UserProfile object. To make sure that applies to every user, we’ll create a UserProfile each time a User is created. To do that. we’ll use the post_save signal (signals doc).

Just under the UserProfile code, you can add that code

And you’re pretty much good to go. You can access the user’s UserProfile using user.user_profile.

Django REST Framework : add an attribute on the fly in a Serializer

Seralizers from DRF are doing a very good job at converting any Model to JSON data. They are even more awesome when you know how to add custom attributes to them.

In my case, I needed to add an attribute based on the current logged in user and related data from my model. To do that, I used a SerializerMethodField.

From the doc :

This is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object.

And the example :

Here’s a preview of how I implemented it :

Basically, this sets a field to True or False if the current user is ‘liking’ the Post object.

This is a pretty neat feature that I don’t want to forget about, so that’s why I’m writing it down here.

Django : resize an image on upload

This is a typical use-case : your site/app allows users to upload a picture. But you don’t want to store full size 8Mb picture, and still, it’s comfortable for the user to not have to manually resize the image before uploading it. The solution : resizing the image “on the fly” when receiving it on the server side.

Another use-case, also quite common : you need to generate a thumbnail for the uploaded picture. The following code will help you too.

This script is re-sizing the image only if it’s a new PicturePost (we check that the object key isn’t set).

We’re doing some calculation to get the right ratio before re-sizing the image. We can’t use the thumbnail() method because we want to resize based only on the width of the image. The thumbnail() method will resize the image based on the biggest between width and height.

We convert the image to jpeg with a 90 quality (the default is 75, 100 meaning no jpeg compression at all).

We also keep the exif information if its exists. By default, it’ll disappear, so we have to manually add them again when saving the resized file.

Once it’s resized, we save the object into the database.

You can also use the same logic to create a thumbnail of the image and store it into another ImageField field. 😉

Quick guide about Django translation

The documentation of translation in Django is pretty well done, but quite long. If you want to setup it up easily, here are the steps.

Translation Setup

Make sure you have gettext installed on your machine. I wrote an article about the OSX specificities.

Create a locale folder inside your main project folder

Django will create subfolders in the locale folder for each language you want to support.

Make sure you include the middleware class in your settings.py file, create or modify the languages settings and set the LOCALE_PATH variable :

Depending on your project structure, you might need to change the locale path to suit your needs. It’s often the cause of the translations not working !

Translation in .py files

We create an alias to it’s easier to use and I think it makes it more readable.

We can add a special comment which will be displayed in the translation file. It can be useful for your translators.

There are a lot of other possibilities. Please read the documentation.

Translation in templates

We need to indicate that we’re using translation, so put that code somewhere near the top of your template.

Then it’s pretty easy

Again, a lot of options and other methods are available, please read the doc.

Create the language files

Fortunately, Django is doing that for us ! Let’s create the french file :

Django will create the file in mysite/locale/fr/LC_MESSAGES/django.po

It’ll look like this :

You simply have to fill out msgstr with the translated phrase.

If you add new phrases in your code, just run

It’ll update all the languages.

Now, the last step : compiling the files into .mo files (binary files optimized for gettext)

And you’re pretty much done. It’s really awesome to see how easy it is.

gettext issue when using Django Translation in OSX

I ran into an issue when generating my language files for Django.

This is because OSX has an old version of gettext installed. To use the last one, install it with homebrew and force homebrew to override OSX gettext command.

And then, no more problems !



Setup environment to work with Django CMS on OSX

Getting the whole python / environment / Django / server running is not that easy when you’re not familiar with it, especially if you’re used to use Apache/MySQL combo. I wrote that guide as a reminder, but I’m sure it can help you setup a Django CMS site pretty easily.

Continue reading Setup environment to work with Django CMS on OSX