Skip to main content

Package to handle database translation in your Django apps

Project description

Django Database Translation

Description

Natively, Django only handles hardcoded text translation and cannot translate your database. This package aims to assist you in translating the entries of your database. It is fairly easy to setup and use, as demonstrated below.

The three main actions of the program are:

  • Automatically generates database entries for any field that must be translated
  • Allows you to access the translations directly from your model's admin
  • Provides a custom tag for translating in HTML

Please note, this does not TRANSLATE for you. It creates the entry in the database for your translation, which you have to fill. Here's how it works in practice:

  • I have registered 3 languages: French, English, Italian
  • I have registered the "Project" model and said it must be translated
  • I have registered 2 fields within the Project model, "name" and "description", as field that will require translations
  • Whenever I create a new project, 6 new translation entries will be create: "name" in 3 languages, and "description" in 3 languages.
  • If I go in my "Project" admin, I will be able to directly edit those 6 translations
  • The translations can then be called in templating using our custom tag

What it contains

Here's a quick recap of what this package contains:

  • 4 new database tables:
    • Field (ddt_fields)
    • Item (ddt_items)
    • Language (ddt_languages)
    • Translation (ddt_translations)
  • A few class extenders:
    • TranslatedAdmin to extend your admins
    • TranslatedModel to extend your models (also provides many useful methods)
  • Some utility:
    • LanguageSelection, a form that can be used in the frontend to pick a language
    • update_user_language, a function that updates the user language for both django and our app
    • get_translation_from_item, useful if you need to translate an item BEFORE sending it as JSON

It contains other elements, but this is what you will be using 99% of the time.

Basic setup and usage

1. Installation

First, we must install the package:

  • Install the package with pip install django-database-translation
  • In settings.py, in your INSTALLED_APPS, add "django_database_translation" (note that we are using underscores this time)
  • Then run the python manage.py migrate command to create the 4 new tables

2. Updating your models

The point here is to "flag" which models have fields that must be translated. As a result, we will extend the models, and change the fields:

  • Extend a model using TranslatedModel for any model that contains TranslatedFields
  • Change any field that will be translated to a TranslatedField (it is a ForeignKey to our Item model)

Here's an example of code:

from datetime import datetime
from django.db import models
from django_database_translation.fields import TranslatedField
from django_database_translation.models import TranslatedModel

class Project(TranslatedModel):  # <-- Extended class
    title = TranslatedField(  # <-- Field changed
        related_name="portfolio_project_title",
        verbose_name="Title"
    )
    description = TranslatedField(  # <-- Field changed
        related_name="portfolio_project_description",
        verbose_name="Description"
    )
    date_posted = models.DateField(
        db_index=True,
        default=datetime.now,
        help_text="Date displayed on the frontend",
        null=False,
        verbose_name="Posted on",
    )
    image = models.ImageField(
        help_text="Must be a square. Will be automatically resized to 200x200.",
        null=False,
        upload_to="portfolio/projects/",
    )

3. Updating your admins

Now that our models have been updated, we can update their admins. Note that you must only update the admins of models that have been extended with TranslatedModel.

Simply extend your admin using the TranslatedAdmin class:

from django_database_translation.admin import TranslatedAdmin

class ProjectAdmin(TranslatedAdmin):  # <-- Extended class
    # Your code, no changes here

Now you will be able to edit translations directly from your admins.

4. Setting up the database

Now we need to manually create a few entries in both our Language and Field models. Do not worry about Item and Translation, their content will be generated automatically.

--> Language

In this table, simply create all the languages available on your website. Make sure that the django_language_name matches an entry in LANGUAGES from settings.py.

# If settings.py is like this:
LANGUAGES = (
    ("fr-fr", "Français"),
    ("en-us", "English"),
)
# Make sure your "django_language_name" is either "fr-fr" or "en-us"

--> Field

Here you must simply register all the fields you've changed to TranslatedField. Make sure their name matches the actual name of the field.

--> Sidenote

If you already had database entries in your models, you'll notice that the Translation model already has a bunch of entry. Technically, an entry has been created for each of your model entry, in each language, and for each field.

5. Translate your entries

Now that everthing is setup, you can go in your admin and go in any of your database entry. If it is a model that uses TranslatedModel and its admin is TranslatedAdmin, you'll be able to see the translations directly in its admin. Go ahead and translate anything that must be translated.

6. Displaying translations

There are two ways of displaying translations for your users:

  • If you're using a templating system (HTML), then you can simply load our custom tag {% load ddt_tags %} and then use {% db_trans item %} where "item" is your TranslatedField
  • However, if you're using AJAX/JSON, you need to handle the translation beforehand. To do so, you can use the get_translation_from_item function from django_database_translation.utils

Here's the code of the function:

def get_translation_from_item(item=None, item_id=None, language=None, language_id=None, as_text=False):
    """
    Description:
        Returns a Translation object or text when given an Item and a Language
        You must provide either "item" or "item_id"
        You must provide either "language" or "language_id"
    Args:
        item (Item, optional): Item instance from the translation app. Defaults to None.
        item_id (int, optional): ID of the Item instance. Defaults to None.
        language (Language, optional): Language instance from the translation app. Defaults to None.
        language_id (int, optional): ID of the Language instance. Defaults to None.
        as_text (bool, optional): Indicates whether to return the instance or its text. Defaults to False.
    Raises:
        TypeError: must provide either 'item' or 'item_id'
        TypeError: must provide either 'language' or 'language_id'
    Returns:
        Translation/String/None: Either a Translation instance, the Translation's text, or None
    """
    # Checking if we have the right parameters
    if (not item and not item_id) or (item and item_id):
        raise TypeError("You must provide either 'item' or 'item_id'. Not none, nor both.")
    if (not language and not language_id) or (language and language_id):
        raise TypeError("You must provide either 'language' or 'language_id'. Not none, nor both.")
    # Keeping only one of each
    params = {
        "item": item,
        "item_id": item_id,
        "language": language,
        "language_id": language_id,
    }
    params = {key: value for key, value in params.items() if value}
    # Finding the translation instance and returning it
    try:
        translation_model = apps.get_model("django_database_translation", "Translation", True)
        translation = translation_model.objects.get(**params)
        if as_text:
            return translation.text
        else:
            return translation
    except translation_model.DoesNotExist:
        return None

Addtionnal information

Model.objects.bulk_create()

If a model is extended using TranslatedModel, it will not be able to use its .bulk_create() method. We are forced deactivate it as our program uses signals to work, and .bulk_create() does not trigger signals.

Choosing a language

As you've seen, Django uses LANGUAGES in the settings to figure out which language you have. But our app uses the Language database/model. To make it easier, we've created:

  • A form that allows user to pick a language in the frontend
  • A function that updates both Django and our app "current language"

If you wish to use it:

  • Form: from django_database_translation.forms import LanguageSelection
  • Function : from django_database_translation.utils import update_user_language
  • The function takes the "request" and the language ID as argument. Call it when the form is valid.

Here's the definition:

from django.utils.translation import activate, LANGUAGE_SESSION_KEY

def update_user_language(request, language_id):
    """
    Description:
        Updates the user current language following Django guildelines
        This will allow for both "Django" frontend translations and "our app" database translation
    Args:
        request (HttpRequest): Request object from Django, used to get to the session
        language_id (id/str): ID of the language in our database
    """
    from .models import Language
    language = Language.objects.get(id=language_id)
    activate(language.django_language_name)
    request.session[LANGUAGE_SESSION_KEY] = language.django_language_name

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_database_translation-1.0.0.tar.gz (17.8 kB view details)

Uploaded Source

Built Distribution

django_database_translation-1.0.0-py3-none-any.whl (18.9 kB view details)

Uploaded Python 3

File details

Details for the file django_database_translation-1.0.0.tar.gz.

File metadata

  • Download URL: django_database_translation-1.0.0.tar.gz
  • Upload date:
  • Size: 17.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.4.0 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.7.0

File hashes

Hashes for django_database_translation-1.0.0.tar.gz
Algorithm Hash digest
SHA256 8ba02f1f6e228bb80df09419ec12a6dceaede3fa01cc89e062b1e305f4036101
MD5 cd3bd8515a0ec8c9e302831e409a34c9
BLAKE2b-256 f982022f2f60e40237ab1f09d98443d6e799222f260eb124d14bf562bd670e4f

See more details on using hashes here.

File details

Details for the file django_database_translation-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: django_database_translation-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.4.0 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.7.0

File hashes

Hashes for django_database_translation-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c84f98f98a249d9dd045ea3f630b2974cd023f1abf7db7a8f75dd0922010b748
MD5 da226d0693715fe3a046c442377b4d40
BLAKE2b-256 2a9fd660da0f19a2eb4042ada813bb8e577ed108a7501d6a76925a9e32fe2754

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page