Search code examples
djangodjango-modelsmultilingual

Best practice: Django multilanguage


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


Solution

  • 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.