Отображение количества экземпляров для каждой модели в индексе администратора Django - PullRequest
4 голосов
/ 05 июня 2011

Мне нужно отобразить количество объектов на главной странице администратора сайта django. Например, в списке моделей мне нужно отобразить

Elephants (6) 

вместо

Elephants

Я добавил этот код в свою модель:

class Elephant(models.Model):
    ....
    class Meta:
        verbose_name_plural = 'Elephants ' + '(' + unicode(count_elephants()) + ')'

где count_elephants () вычисляет количество объектов. Проблема в том, что verbose_name_plural вычисляется при запуске сервера и не вызывается при удалении / вставке объектов, поэтому это вычисленное значение становится неактуальным. Можно ли сделать это правильно? Спасибо!

1 Ответ

7 голосов
/ 05 июня 2011

Поскольку verbose_name_plural используется во многих других целях, лучшим способом сделать это будет изменение представления индекса администратора и шаблона администратора.

Однако, поскольку приложение администратора может измениться, это, вероятно, связано сконкретная версия Django.Я прилагаю, например, модифицированный администратор, взятый из django 1.2.5.

(Примечание: я буду использовать замену на месте для метода индекса, но, вероятно, будет лучше использовать его подкласс вместо замены метода)

Для начала скопируйте из django / contrib / admin / sites.py метод AdminSite.index и его требуемый импорт, и измените его, чтобы включить счетчики (одна строка изменена, ищите «ЭТА ЛИНИЯ БЫЛА ДОБАВЛЕНА»"). Добавьте его в любой из ваших файлов admin.py или в другое подходящее место:

from django.utils.text import capfirst
from django import template
from django.shortcuts import render_to_response
from django.views.decorators.cache import never_cache
from django.utils.translation import ugettext as _

def index_with_count(self, request, extra_context=None):
    """
    Displays the main admin index page, which lists all of the installed
    apps that have been registered in this site.
    """
    app_dict = {}
    user = request.user
    for model, model_admin in self._registry.items():
        app_label = model._meta.app_label
        has_module_perms = user.has_module_perms(app_label)

        if has_module_perms:
            perms = model_admin.get_model_perms(request)

            # Check whether user has any perm for this module.
            # If so, add the module to the model_list.
            if True in perms.values():
                model_dict = {
                    'name': capfirst(model._meta.verbose_name_plural),
                    'admin_url': mark_safe('%s/%s/' % (app_label, model.__name__.lower())),
                    'perms': perms,
                    'count': model.objects.count(), # THIS LINE WAS ADDED
                }
                if app_label in app_dict:
                    app_dict[app_label]['models'].append(model_dict)
                else:
                    app_dict[app_label] = {
                        'name': app_label.title(),
                        'app_url': app_label + '/',
                        'has_module_perms': has_module_perms,
                        'models': [model_dict],
                    }

    # Sort the apps alphabetically.
    app_list = app_dict.values()
    app_list.sort(lambda x, y: cmp(x['name'], y['name']))

    # Sort the models alphabetically within each app.
    for app in app_list:
        app['models'].sort(lambda x, y: cmp(x['name'], y['name']))

    context = {
        'title': _('Site administration'),
        'app_list': app_list,
        'root_path': self.root_path,
    }
    context.update(extra_context or {})
    context_instance = template.RequestContext(request, current_app=self.name)
    return render_to_response(self.index_template or 'admin/index.html', context,
        context_instance=context_instance
    )

site.index = never_cache(type(site.index)(index_with_count, site, AdminSite))

Теперь скопируйте файл django / contrib / admin / templates / admin / index.html в admin / index.html.в любой из ваших папок шаблонов, чтобы переопределить исходный шаблон и изменить его, чтобы показать количество:

{% extends "admin/base_site.html" %} 
{% load i18n %} 

{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% load adminmedia %}{% admin_media_prefix %}css/dashboard.css" />{% endblock %} 

{% block coltype %}colMS{% endblock %} 

{% block bodyclass %}dashboard{% endblock %} 

{% block breadcrumbs %}{% endblock %} 

{% block content %}
<div id="content-main">

{% if app_list %}
    {% for app in app_list %}
        <div class="module">
        <table summary="{% blocktrans with app.name as name %}Models available in the {{ name }} application.{% endblocktrans %}">
        <caption><a href="{{ app.app_url }}" class="section">{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}</a></caption>
        {% for model in app.models %}
            <tr>
              <th scope="row">
                {% if model.perms.change %}
                    <a href="{{ model.admin_url }}">{{ model.name }}</a>
                {% else %}
                    {{ model.name }}
                {% endif %}
                ({{ model.count }})
              </th>

            {% if model.perms.add %}
                <td><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
            {% else %}
                <td>&nbsp;</td>
            {% endif %}

            {% if model.perms.change %}
                <td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
            {% else %}
                <td>&nbsp;</td>
            {% endif %}
            </tr>
        {% endfor %}
        </table>
        </div>
    {% endfor %}
{% else %}
    <p>{% trans "You don't have permission to edit anything." %}</p>
{% endif %}
</div>
{% endblock %}

{% block sidebar %}
<div id="content-related">
    <div class="module" id="recent-actions-module">
        <h2>{% trans 'Recent Actions' %}</h2>
        <h3>{% trans 'My Actions' %}</h3>
            {% load log %}
            {% get_admin_log 10 as admin_log for_user user %}
            {% if not admin_log %}
            <p>{% trans 'None available' %}</p>
            {% else %}
            <ul class="actionlist">
            {% for entry in admin_log %}
            <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
                {% if entry.is_deletion %}
                    {{ entry.object_repr }}
                {% else %}
                    <a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
                {% endif %}
                <br/>
                {% if entry.content_type %}
                    <span class="mini quiet">{% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %}</span>
                {% else %}
                    <span class="mini quiet">{% trans 'Unknown content' %}</span>
                {% endif %}
            </li>
            {% endfor %}
            </ul>
            {% endif %}
    </div>
</div>
{% endblock %}

Это сделает это. (Вам все еще нужно будет изменить представление app_index, чтобы правильно видеть счетчики виндексные страницы приложения, я оставляю вам это в качестве упражнения: -)

...