Reputation: 3638
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:
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:
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
Upvotes: 10
Views: 8324
Reputation: 36260
If you don't want to manage each model manually you can try something like django-linguo. It creates the translations for the fields you like based on your Meta class translate attribute and on your LANGUAGES setting in your settings.py file.
I strongly recommend checking out some of the internationalization packages available for Django like django-rosetta, and django-linguo. Django-linguo helps translate model content, while django-rosetta looks like it adds an admin interface for your translations.
I haven't really played with django-rosetta yet but it also looks interesting. Hope this helps :)
Upvotes: 1
Reputation: 1950
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.
Upvotes: 8
Reputation: 616
Based on your current model and the three possibilities you described, you could try the following to translate your model information:
class Book(models.Model):
language = models.CharField(max_length=2)
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 BookTranslation(models.Model):
book = models.ForeignKey(Book, related_name="translations")
language = models.CharField(max_length=2)
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)
language = models.CharField(max_length=2)
chapter = models.SmallIntegerField()
title = models.CharField(max_length=255, blank=True)
pages = models.SmallIntegerField()
pub_date = models.DateTimeField(auto_now_add=True)
class ChapterTranslation(models.Model):
chapter = models.ForeignKey(Chapter, related_name="translations")
title = models.CharField(max_length=255, blank=True)
pages = models.SmallIntegerField()
Then in your views you can do something like this:
# Get user language, default 'en'
lang = request.session.get('django_language', 'en')
book = Book.objects.get(...)
book_translation = book.translations.filter(language__exact=lang)[0]
return render_to_response(...,
{
'book': book_translation
})
As Vladislav suggested in his answer, check out all the different django-multilingual currently available as an alternative to what I described here.
As for translating your website static content, that's pretty straightforward. Check out Django Internationalization.
Upvotes: 3