Search code examples
pythondjangodjango-rest-frameworkdjango-translated-fields

Why django translations don't work in celery task


I'm having problems with django text translations. My translation works fine in serializer, not in celery task.

I have one "Person" model. There are 3 fields in the Person model. One of the fields is gender. The genders are defined in the "enums.py" file. In the serializer, the "get_gender_display()" method of the "Person" model works fine, but when I do the same in the celery task, it does not translate. It doesn't work even though I specify activate("tr") in the Celery task.

I call the celery task from the serializer's create() method

enums.py

from django.utils.translation import gettext_lazy as _
class GenderTypeEnum:
    FEMALE = 1
    MALE = 2
    UNKNOWN = 3

    types = (
        (FEMALE, _("Female")),
        (MALE, _("Male")),
        (UNKNOWN, _("Unknown"))
    )

models.py

from django.db import models
from .enums import GenderTypeEnum
from django.utils.translation import gettext_lazy as _

class PersonModel(models.Model):
    name = models.CharField(
        max_length=75,
        verbose_name=_('Name')
    )

    last_name = models.CharField(
        max_length=75,
        verbose_name=_('Last Name')
    )

    gender = models.PositiveIntegerField(
        choices=GenderTypeEnum.types,
        default=GenderTypeEnum.UNKNOWN,
        verbose_name=_('Gender')
    )

tasks.py

from celery import shared_task
from .models import PersonModel
from django.utils.translation import gettext_lazy as _, activate, get_language
@shared_task
def test():
    activate("tr")
    
    qs = PersonModel.objects.all()
    activate("tr")
    print(get_language()) # --> tr
    
    for obj in qs:
        print(obj.get_gender_display()) # --> always english, not translated

serializers.py

from rest_framework import serializers
from .models import PersonModel
class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model=PersonModel
        fields = '__all__' 

    def create(self, validated_data):
        
        activate("tr")
    
        qs = PersonModel.objects.all()
        activate("tr")
        print(get_language()) # --> tr
    
        for obj in qs:
            print(obj.get_gender_display()) # --> work fine, translated     
        
        # run celery task
        test.delay()

        return super().create(validated_data)

Solution

  • You didn’t clarify a little, do the translations inside celery not work at all for you or don’t work during deployment?

    I had a similar problem. All translations worked fine with activate() locally inside celery task, but when I deployed my project with docker, I didn't get any translated strings. The solution that worked for me is to run compilemessages when starting the docker-compose celery worker service, as well as with the service where django is running. Hope it helps!