django - 如何使用 Django 和 pgetttext() 在 .po 文件中获取 msgctxt
问题描述
我正在为具有英语和西班牙语的预订应用程序编写通知模块。它应该足够灵活以处理任何模型和任何状态变化(例如创建、更新、取消等)。
get_subject() 函数将使用相关对象的模型名称(例如约会)和状态动词为通知准备一个“主题”行。所以我们应该得到'Appointment 123ABC modified'或'Payment 789XYZ created'等。除了允许西班牙语单词的语法性别之外,我让它在翻译方面工作。因此,“Appointment 123ABC modified”将是“Cit a 123ABC actualizad a ”,而“Payment 123ABC modified”将是“Pag o 123ABC actualizad o ”。
我知道解决方案是在 .po 文件中使用 pgettext(context, string) 以及 msgctxt,但我只是不知道如何让 manage.py makemessages 在准备 .po 文件时添加 msgctxt .
我尝试了各种直接编辑 .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)
解决方案
来自的错误消息msgfmt
表明您对.po
文件中的 msgctxt 使用了错误的语法。它应该是这样的:
msgctxt "abbreviated_weekday"
msgid "Sun"
msgstr ""
但是您应该提取字符串而不是操作.po
文件。解决方案是生成一个包含所有必需调用的虚拟源文件,pgettext()
以便makemessages
.
在您的代码中,对的调用pgettext()
在变量中而不是字符串文字中具有消息上下文,并且此类调用当然会被xgettext()
.
推荐阅读
- python - 在python中添加基于计数和唯一计数的列
- sql-server - 全文搜索排除前缀
- c - 代码分段错误(核心转储) pthread 创建
- python - 为arduino检测到加载颜色问题
- c# - 在 UWP 中创建/编写/压缩/解压缩文件
- vba - 在 2 个不同的行中查找匹配项 - IF Else 失败
- python - 如何通过多个规则加快形成新列
- javascript - 如何撤消 $("button").remove()?
- mysql - MySQL依靠前提条件?
- python - Windows 10、Python 3.6 和 64 位上的 TensorFlow 加载 DLL 失败