【问题标题】:How to get msgctxt in .po file with Django and pgetttext()如何使用 Django 和 pgetttext() 在 .po 文件中获取 msgctxt
【发布时间】:2020-12-09 02:02:55
【问题描述】:

我正在为具有英语和西班牙语的预订应用程序编写通知模块。它应该足够灵活,可以处理任何模型和任何状态变化(例如创建、更新、取消等)。

get_subject() 函数将使用相关对象的模型名称(例如约会)和状态动词为通知准备一个“主题”行。所以我们应该得到'Appointment 123ABC modified'或'Payment 789XYZ created'等。除了允许西班牙语单词的语法性别之外,我让它在翻译方面工作。因此,'Appointment 123ABC modified' 将是 'Cita 123ABC actualizada' 而说,'Payment 123ABC modified' 将是 'Pago 123ABC实际o'。

我知道解决方案是使用 pgettext(context, string) 以及在 .po 文件中包含 msgctxt,但我只是不知道如何让 manage.py makemessages 在它准备好时添加 msgctxt .po 文件。

我尝试了各种直接编辑 .po 的方法,但在运行 compilemessages 时出现错误(执行 msgfmt 失败:backend/locale/es/LC_MESSAGES/django.po:3966: 重复消息定义...)和无论如何,makemessages 只是覆盖了我的编辑。

我不确定我需要的只是 po 文件的正确格式,还是我是否需要正确的方式让 makemessages 为我的情况正常工作。任何帮助将不胜感激。

class Notification(Uuidable, Timestampable):
    user = models.ForeignKey(User, related_name='notifications', verbose_name=_('notifications'), on_delete=models.CASCADE)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, blank=True, null=True)
    object_id = models.UUIDField(blank=True, null=True)
    content_object = GenericForeignKey('content_type', 'object_id')
    subject = models.CharField(max_length=256, verbose_name=_('subject'))
    status_type = models.CharField(choices=NOTIFICACTION_STATUS_VERBS, max_length=256, verbose_name=_('status type'))
    details = models.TextField(null=True, blank=True, verbose_name=_('details'))
    read_at = models.DateTimeField(null=True, blank=True, verbose_name=_('read at'))
    email_sent_at = models.DateTimeField(null=True, blank=True, verbose_name=_('email sent at'))
    pusher_sent_at = models.DateTimeField(null=True, blank=True, verbose_name=_('pusher sent at'))

    def generate_subject(self):
        class_name = self.content_object._meta.verbose_name
        context = str(class_name).lower()

        with translation.override(self.user.locale.split('-')[0]):
            class_name_translated = translation.gettext(class_name).capitalize()
            status_translated = translation.pgettext(context, str(self.status_type))

        subject = f'{class_name_translated} {self.content_object.display_id} {status_translated}'
        return subject

    def __str__(self):
        return self.subject

    def get_email_template(self, template_type):
        return NOTIFICATION_EMAIL_TEMPLATES[self.content_object.__class__.__name__][self.status_type][template_type]

    def save(self, *args, **kwargs):
        self.subject = _(self.generate_subject())
        return super(Notification, self).save(*args, **kwargs)

【问题讨论】:

    标签: django internationalization gettext


    【解决方案1】:

    来自msgfmt 的错误消息表明您对.po 文件中的msgctxt 使用了错误的语法。它应该是这样的:

    msgctxt "abbreviated_weekday"
    msgid "Sun"
    msgstr ""
    

    但是您应该提取字符串而不是操作.po 文件。解决方案是生成一个虚拟源文件,其中包含对pgettext() 的所有必需调用,以便makemessages 正确提取消息。

    在您的代码中,对pgettext() 的调用将消息上下文保存在变量中而不是字符串文字中,这样的调用当然会被xgettext() 忽略。

    【讨论】:

      猜你喜欢
      • 2012-04-22
      • 1970-01-01
      • 2011-06-08
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 2013-01-27
      • 2013-04-04
      相关资源
      最近更新 更多