【问题标题】:How to make Django admin honor grammatical cases in languages like Polish?如何让 Django 管理员尊重波兰语等语言的语法案例?
【发布时间】:2017-08-02 16:19:06
【问题描述】:

Django 允许覆盖Modelverbose_nameverbose_name_plural,这允许我们为非英语语言指定正确的复数形式Model(例如Kandydaci 作为Kandydat 的复数形式)而不是默认的 Kandydats 在波兰语中看起来很奇怪)。

但是,对于具有语法大小写的语言来说,这还远远不够。例如,Django Admin 兴高采烈地向我们展示了这样的内容:

(其中Zaznacz kandydat do zmiany 代表Select kandydat to change - KandydatModel 的名称)

这是不正确的。在这句话中,型号名称应该已经显示在accusative case 中,即kandydata。但是,我不能简单地指定这个Model 中的verbose_nameKandydata,因为这也会影响所有需要nominative case 的地方——到目前为止,我已经找到了一个这样的地方,这是标题表格列:

这是不正确的,因为应该将表格标题称为 Kandydat 而不是 Kandydata

如何解决这个问题?

【问题讨论】:

  • 注意:应用只需要一种语言,那就是波兰语。
  • 以下答案对您的问题有帮助吗?
  • @nik_m 我很快就会检查出来,到目前为止,我不得不转移到项目的另一个部分,并且不得不将管理工作留到稍后。但是几天后我肯定会回到管理员那里,然后我会检查你的答案,对此我非常感激。抱歉耽搁了,但我不得不这样做。
  • 是的,没问题!我很抱歉这么急:)

标签: django internationalization django-admin


【解决方案1】:

字符串'Select <verbose_name> to change'admin's main view中声明

self.title = title % force_text(self.opts.verbose_name)

作为{{ title }}模板变量

{% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}

因此,触摸内置视图是毫无疑问的。但是还有另一种方法!你看,Django Admin 模板充满了{% block %}s 作为占位符来覆盖它们。阅读有关overriding Admin templates 的官方文档的更多信息。

所以,对于你的问题。

  1. 在项目的根目录下创建一个目录templates(如果它不存在)。
  2. my_project/templates/ 下创建另一个admin
  3. my_project/templates/admin/ 下创建一个文件change_list.html
  4. my_project/templates/admin/change_list.html 里面放这些:

    {% extends 'admin/change_list.html' %}
    
    {% load myutils_filters %}
    
    {% comment %}
    You have to create an app that will hold all common tags/filters
    that are re-usable across your entire project.
    The model class itself is passed as cl.model
    {% endcomment %}
    
    {% block content_title %}{{ block.super|to_accusative:cl.model }}{% endblock %}
    
  5. 在您的 myutils/templatetags/myutils_filters.py 文件中放置这些:

    from django import template
    from django.utils.html import format_html
    from django.utils.encoding import force_text
    
    register = template.Library()
    
    @register.filter()
    def to_accusative(value, model):
        verbose_name = model._meta.verbose_name  # declared in Meta
        new_name = force_text(model.accusative case())  # a custom class method (lives in your Model)
        return format_html(value.replace(verbose_name, new_name))
    
  6. 最后,在您应用的models.py 下,在每个模型class 下定义一个classmethod 方法,如下所示:

    from django.db import models
    from django.utils.translation import ugettext_lazy as _
    
    class MyModel(models.Model):
        # model fields here
    
        def __str__():
            return self.a_field
    
        class Meta:
            verbose_name = 'verbose name'
            verbose_name_plural = 'verbose name plural'
            # accusative_case = 'accusative name case' # BAD. Raises error. Implement a class method intead ;)
    
        @classmethod
        def accusative_case(cls):
            # You'll define the Polish translation as soon as you run makemessages
            return _('Name in english of the accusative case')
    
  7. 运行manage.py makemessagesmanage.py compilemessages,重新加载浏览器,瞧!

注意:以上内容可能看起来有点hackish,但效果很好。在本地测试并有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    相关资源
    最近更新 更多