开发者

How to display total record count against models in django admin

Is there a neat way to 开发者_StackOverflow社区make the record/object count for a model appear on the main model list in the django admin module?

I have found techniques for showing counts of related objects within sets in the list_display page (and I can see the total in the pagination section at the bottom of the same), but haven't come across a neat way to show the record count at the model list level.


I would look into the models.Manager class. A subclass of Manager will allow you to add table-level functionality to your models. A Manager method can return any data you want and there is an interesting example in the Django DB API documentation. You may then be able to pull this into Admin by adding a admin inner class to your model.


from django import template
from django.db.models.loading import get_model

register = template.Library()

@register.simple_tag()
def get_model_count(admin_url):
  app_label, model_name = admin_url.split('/')[:2]
  return get_model(app_label, model_name, seed_cache=False).objects.count()

Then copy and override "/templates/admin/index.html" from "django's contrib/admin/templates/index.html".

At the top add:

{% load NAME_OF_YOUR_TAG_FILE %}

Add the following call after the model name or wherever:

{% get_model_count model.admin_url %}

This fits nicely into this use case. You're done!


I didn't find any nice way to add count of models in the main admin page, but here is the solution that I finally use.

In short I compute the counts of each models in signals post_delete and post_save methods, store the variables in the custom request (in a map) and display it in the extended admin index.html by simply checking with an if for each desired models.

The extended templates/admin/index.html:

{% if model.perms.change %}
    <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }} 
    {% if model.name == "Mymodel1_verbose_name_plural" %} ({{ MODELS_COUNT.Mymodel1}}) {% endif %}
    </a></th>
{% else %}

My custom request in util/context_processors.py:

from myproject import settings

def myproject(request):
    return {
        'request' : request,
        'MODELS_COUNT' : settings.MODELS_COUNT
    }

In my settings.py:

MODELS_COUNT = {
      'Mymodel1': None,
      'Mymodel2': None       
}

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'myproject.util.context_processors.myproject',
)

In myproject.__init__.py:

from django.db.models.signals import post_save, post_delete

def save_mymodel1_count(sender, instance=None, **kwargs):
    if kwargs['created']:
        settings.MODELS_COUNT['Mymodel1'] = Mymodel1.objects.count()
def delete_mymodel1_count(sender, instance=None, **kwargs):
    settings.MODELS_COUNT['Mymodel1'] = Mymodel1.objects.count()
settings.MODELS_COUNT['Mymodel1'] = Mymodel1.objects.count()

post_save.connect(save_mymodel1_count, sender=Mymodel1)
post_delete.connect(delete_mymodel1_count, sender=Mymodel1)

If you have lots of models, I suggest that you transform this in a more generic solution.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜