16👍
I wanted the same functionality for my site and added it by doing slight modifications to the core django system.
Step 1:
First we need a way to indicate which models should have their properties listed. Add the following code to the models for which you want the instances listed (in models.py):
class Meta:
list_instances = True
Step 2:
We need to modify Django to recognize and read this new attribute. In core-django file: db/models/options.py, roughly at line 22 append ‘list_instances’ to DEFAULT_NAMES:
DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering',
'unique_together', 'permissions', 'get_latest_by',
'order_with_respect_to', 'app_label', 'db_tablespace',
'abstract', 'managed', 'proxy', 'auto_created', 'list_instances')
and in the same file, roughly at line 52, create a default field for this attribute right after the other attributes :
self.list_instances = False
Step 3:
We need to pass this information along to the template that generates the index page. In core-django file: contrib/admin/sites.py, inside index() method and inside the “if has_module_perms:” part, add the following code:
instances = []
if (model._meta.list_instances == True):
instances = model_admin.queryset(None)
This will create the list of instances to show, but only if the list_instance attribute is set. In the same file, a few lines further down, append these values to the “model_dict” construct.
model_dict = {
'name': capfirst(model._meta.verbose_name_plural),
'admin_url': mark_safe('%s/%s/' % (app_label, model. __name__.lower())),
'perms': perms,
'list_instances':model._meta.list_instances,
'instances': instances,
}
Step 4:
The final step is to modify the template to support this. Either edit the core-django file /contrib/admin/templates/admin/index.html or copy this file to the templates/admin/ directory of your specific app. Add a few lines after the standard code for generating rows to generate the “sub-rows” if applicable. Roughly at line 40, right between “/tr>” and “{% endfor %}”:
{% if model.list_instances %}
{% for instance in model.instances %}
<tr>
<td colspan="2" style="padding-left: 2em;">{{ instance }}</td>
{% if model.perms.change %}
<td><a href="{{ model.admin_url }}{{ instance.id }}/" class="changelink">{% trans 'Change' %}</a></td>
{% else %}
<td> </td>
{% endif %}
</tr>
{% endfor %}
{% endif %}
This will cause the item to be listed with the name generated by the unicode() method in the model.
Step 5:
Lo and behold! It should look something like this:
Edit:
Optional Step 6:
If you want the instance names to be clickable too, just change the template (index.html) and replace:
<td colspan="2" style="padding-left: 2em;">{{ instance }}</td>
with:
<td colspan="2" style="padding-left: 2em;">
{% if model.perms.change %}
<a href="{{ model.admin_url }}{{ instance.id}}">{{ instance }}</a>
{% else %}
{{ instance }}
{% endif %}
</td>
2👍
UPDATE Setomidor answer for django 10
Always great to come back to this clean solution!
step 2 – it is around line 125 (was 52)
step 3 – in sites.py – update the new method –
_build_app_dict
inside the for loop : for model, model_admin in models.items():
add step 3 as said around lines 430 and 460
instances = []
if (model._meta.list_instances == True):
instances = model_admin.get_queryset(None)
1👍
You can do this by changing the various admin templates – the root one is called app_index.html
and controls what gets displayed there. The best way to investigate what’s happening where is to install django-debug-toolbar and then look at the templates being used for each view to figure out how to customise.
- Django: Limiting the number of relationships in a OnetoMany relationship
- Specify order of columns in SELECT with UNION using Django ORM
- Extending custom router to default router across apps in Django Rest Framework
- How to do less than or equal to and greater than equal to in django filter?
- Django + MySQL – Unknown encoding: utf8mb4