Django: links in object list
Posted on Wed 21 May 2014 in Programming
In my projects I usually use links to related items in the admin change_list.
utils.py
I have this in utils.py
from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from django.core import urlresolvers
from django.utils.datastructures import SortedDict
from django.utils.functional import memoize
def get_change_url(obj):
""" Utility method
def server_link(self, obj):
return self.get_change_url(obj.server)
server_link.short_description = _('server')
server_link.allow_tags = True
server_link.admin_order_field = 'server__name'
"""
if obj is None:
return
content_type = get_content_type(obj.__class__)
change_url = urlresolvers.reverse(
"%s:%s_%s_change" % (admin.site.app_name, content_type.app_label, content_type.model),
args=[obj.pk])
return '<a href="%s">%s</a>' % (change_url, obj)
def _get_content_type(klass):
return ContentType.objects.get_for_model(klass)
get_content_type = memoize(_get_content_type, SortedDict(), 2)
I make use of memoize to increase efficiency. I think it is the point between simplicity in code with ease of use. I have also had decorators to repeat less in admin.py but when others saw the code they didn't understand it at first.
admin.py
A usage example: in admin.py (assuming the Link model has a FK called product):
from utils import get_change_url
class LinkAdmin(AdminImageMixin, admin.ModelAdmin):
list_display = ['name', 'is_visible', 'product_link', 'updated_at']
search_fields = ['name', ]
def product_link(self, obj):
return get_change_url(obj.product)
product_link.short_description = 'Product'
product_link.allow_tags = True
product_link.admin_order_field = 'product__name'