Best practice: Django multilanguage

Jiloc picture Jiloc · Apr 1, 2013 · Viewed 7.4k times · Source

i'm a beginner with django. (I just completed the tutorial and following this guide http://www.gettingstartedwithdjango.com) I want to make a site with multilingual content, and i would know which is the best practice, at least with the models:

  1. Use different tables (1 for each language)
  2. Use just one table, using an extra attribute in the model for the language
  3. I have no idea

Vladislav is in right, it all depends on the data the table is containing. So an example:

class Book(models.Model):
    created_at = models.DateTimeField(auto_now_add=True, editable=False)
    name = models.CharField(max_length=255, unique=True)
    plot = models.TextField()
    slug = models.SlugField(max_length=255, blank=True, default='')

class Chapter(models.Model):
    book = models.ForeignKey(Book)
    chapter = models.SmallIntegerField()
    title = models.CharField(max_length=255, blank=True)
    pages = models.SmallIntegerField()
    pub_date = models.DateTimeField(auto_now_add=True)

Possibilities:

  1. I may have a complete book in all languages
  2. I may have a complete book in just 1 language
  3. I may have a complete book in 1 language, but just some chapters in another language

So i think that i must keep one instance of a book for each language which i've got at least one chapter of that book.

I hope that it is clear! Thanks again you all

Answer

Vladislav Mitov picture Vladislav Mitov · Apr 1, 2013

For me, it all depends on the data the table is containing, There is no one size fits all.

For system tables (categories, field choices) I do one table different columns for different languages. Old but fine implementations is django-transmeta.

For tables with a lot of rows - table with common information and a table for translatable one. This way you can add languages on the fly - good for situations when you want to give users big choice of languages. Apparently I'm not sure there is good implementation of this approach. django-hvad is one implementation but it still beta and I personally don't like using it.

Here you can find more information about available plugins.

I can suggest following models.

class Book(models.Model):
    """Model for common book info"""
    created_at = models.DateTimeField(auto_now_add=True, editable=False)
    #Other common fields


class BookTranslation(models.Model):
    """Model for translatable book info"""
    book = models.ForeignKey(Book, related_name="translations")
    language = models.CharField(max_length=2)
    name = models.CharField(max_length=255, unique=True)
    slug = models.SlugField(max_length=255, blank=True, default='')
    plot = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True, editable=False)


class Chapter(models.Model):
    """Model for common chapter info"""
    pub_date = models.DateTimeField(auto_now_add=True)
    pages = models.SmallIntegerField()

    #I'll suggest such relation so you can get the chapters from book 
    #and book translation objects
    #related_name='+' means no related_name
    #You need to specify it when you have 2 FK to same model
    book = models.ForeignKey(Book, related_name='+')
    book_translation = models.ForeignKey(Book, related_name='chapters')


class ChapterTranslation(models.Model):
    """Model for translatable chapter info"""
    chapter = models.ForeignKey(Chapter, related_name="translations")
    language = models.CharField(max_length=2)
    title = models.CharField(max_length=255, blank=True)

In this case it is good that you get familiar with select-related and prefetch-related

In any case you need to build an abstraction on top so it will be comfortable to work with the structure.