Локализация Django с неназванными строковыми аргументами - PullRequest
2 голосов
/ 27 марта 2012

Я создал несколько классов Badge в Django, каждый из которых содержал своего рода описание в строковой переменной:

"You get this badge because you've runned %d meters in %d minutes"
"You get this badge because you've killed %d monsters of the type %s"

и т. Д.И у классов также есть функция get_description(badge_level_requirements), поэтому в шаблонах она будет вызываться вместе со списком для сборки строки для конкретного пользователя:

class RunnerBadge(Badge):
    des=ugettext_lazy("You get this badge because you've runned %d meters in %d minutes")
    def get_description(cls,badge_level_requirements):
        return cls.des%badge_level_requirements

И я сохранил списки требований вбаза данных уже без имен аргументов :( Как показано в примерах, разные классы имеют разное количество значений для заполнения строки, значения также означают разные вещи. Поэтому я не могу назвать имена аргументов.

Однако, если я захочу интернационализировать эти строки, будут ошибки: 'msgid' format string with unnamed arguments cannot be properly localized И языковой файл не может быть сгенерирован для этого.

Есть ли способ обойти эту ошибку?

Обновление

Я сталкивался с этим методом обхода ошибки без изменения базы данных. В базе данных требования к уровню хранятся в текстовом поле в формате dict:

#Requirment of Runner's badge
"{'gold':(100,10),'silver':(50,5),'bronze':(25,2)}"

И в определении класса вручную добавить имена аргументов как 'arg_0', 'arg_1' ... к описаниям. Метод get_description - это изменениеd для предварительной обработки данных перед их использованием для заполнения строк описания.

class RunnersBadge(Badge):
    requirements=#get the previous dict from database
    description="You get this badge because you've runned %(arg_0)d meters in %(arg_1)d minutes"

    @classmethod
    def get_description(cls,level):
        '''
        This is actually a method of parent class Badge
        level is either 'gold','silver' or 'bronze'
        '''
        dic={}
        try:
            for (num,val) in enumerate(cls.requirements[level]):
                dic['arg_'+str(num)]=val
        except TypeError:
            dic['arg_0']=cls.requirements[level]


        return cls.description%dic

Этот метод сохраняет большую часть текущей структуры (логика и база данных).А переводчику просто нужно позаботиться о размещении слов.

Ответы [ 2 ]

5 голосов
/ 27 марта 2012
  1. как в коде, имена переменных должны быть значимыми в их контексте , 'meter_count' и 'minute_count' являются явными по сравнению с 'arg_0' и'arg_1', которые не имеют смысла

  2. использование стандартный перевод в коде Python , он менее подвержен ошибкам и распознается удивительно полезными make-сообщениямикоманда

  3. использовать использовать интерполяцию именованных строк (например, %(day)s) вместо позиционной интерполяции (например, %s или %d) всякий раз, когда у вас есть более одного параметра, потому что порядок параметров может меняться в зависимости от языка.Т.е. в германском и латинском языках обратный порядок имен существительных / прилагательных, даты отображаются по-разному в зависимости от языка и т. Д., И т. Д. *

  4. использование пробег вместо запуска, дважды проверьте синтаксическую достоверность ваших строк перевода на английский язык

Это:

class RunnersBadge(Badge):
    requirements=#get the previous dict from database
    description="You get this badge because you've runned %(arg_0)d meters in %(arg_1)d minutes"

Становится:

from django.utils.translation import ugettext as _

class RunnersBadge(Badge):
    requirements=#get the previous dict from database
    description=_("You get this badge because you've ran %(meter_count)d meters in %(minute_count)d minutes")
1 голос
/ 16 ноября 2012

Чтобы дать другой подход к переводу строк, содержащих данные БД, или к любому другому пользовательскому контенту, я настоятельно рекомендую Bablic . Они отслеживают строки, отображаемые на вашем сайте, и уведомляют вас о новом или непереведенном тексте. Они также могут быть интегрированы с облачными поставщиками переводов, так что даже недавно отправленный контент будет переведен практически сразу, без необходимости отслеживания или внесения каких-либо обновлений в код или конфигурацию на стороне сервера.

Может быть, такой подход вам подойдет больше?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...