How do I get the Django admin to respect grammar cases in languages ​​like Polish?

Django allows you to overwrite verbose_name

and verbose_name_plural

for Model

, which allows us to specify correct plural forms Model

for non-English languages ​​(for example, Kandydaci

as a plural Kandydat

instead of the standard Kandydats

, which looks strange in Polish).

However, this is not enough for languages ​​with grammatical cases. For example, Django Admin happily displays something like this to us:

enter image description here

(Where Zaznacz kandydat do zmiany

means Select kandydat to change

- Kandydat

is a name Model

)

This is not true. In this sentence, the model name must appear in the accusative case , which is kandydata

. However, I cannot simply point out that verbose_name

this Model

is kandydata

, as it will also affect all places where enter image description here

This is incorrect because the table header should be called Kandydat

not kandydata

.

How to fix it?

+3


source to share


1 answer


The line is 'Select <verbose_name> to change'

declared inside the main admin view

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

as a {{ title }}

template variable

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



So touching the inline view is out of the question. But there is another way to do it! You see, Django Admin templates are complete {% block %}

, acting like placeholders to override them. Read more in the official docs overriding admin templates .

So to your question.

  • In the root directory of your project, create a directory templates

    (if it doesn't already exist).
  • The my_project/templates/

    create another one admin

    .
  • In my_project/templates/admin/

    create a file change_list.html

    .
  • Inside, my_project/templates/admin/change_list.html

    put these:

    {% 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 %}
    
          

  • Inside your file myutils/templatetags/myutils_filters.py

    put:

    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))
    
          

  • Finally, below your application, models.py

    in each model, class

    define a method 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')
    
          

  • Launch manage.py makemessages

    , manage.py compilemessages

    restart your browser and voila!

Note. The above might look a little hacky, but it works great. Field tested and working.

+2


source







All Articles