Replace model select widget in admin with a readonly link to the related object

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from django import forms
from django.utils.safestring import mark_safe
from django.utils.html import escape

class ModelLinkWidget(forms.HiddenInput):

    def __init__(self, admin_site, original_object):
        self.admin_site = admin_site
        self.original_object = original_object
        super(ModelLinkWidget,self).__init__()

   
    def render(self, name, value, attrs=None):
        if self.original_object is not None:
            link = '%s%s/%s/%d' % (self.admin_site.root_path,
                                   self.original_object._meta.app_label, 
                                   self.original_object._meta.module_name,
                                   self.original_object.id)
            return super(ModelLinkWidget, self).render(
                name, value, attrs) + mark_safe('<a href="%s">%s</a>' % (link, escape(unicode(self.original_object))))
        else:
            return "None"
                                                                
class ModelLinkAdminFields(object):
    def get_form(self, request, obj=None):
        form = super(ModelLinkAdminFields, self).get_form(request, obj)

        if hasattr(self, 'modellink'):
            for field_name in self.modellink:
                if field_name in form.base_fields:
                    form.base_fields[field_name].widget = ModelLinkWidget(self.admin_site, getattr(obj, field_name, ''))
                    form.base_fields[field_name].required = False
        return form

More like this

  1. Hyperlink read-only ForeignKey objects in admin to their change pages by strangefeatures 1 year, 4 months ago
  2. Readonly admin fields by peritus 4 years, 10 months ago
  3. Allow foreign key attributes in list_display with '__' by jcushman 4 months, 2 weeks ago
  4. Javascript Chain Select Widget by ogo 5 years ago
  5. Django Admin Replacer Code by riccardodivirgilio 2 years, 7 months ago

Comments

romke (on December 12, 2008):

I'd put "self.original_object.pk" instead of "self.original_object.id" as sometimes you have primary key named differently than "id"

#

paulmcm (on February 11, 2009):

This worked for me, except when I wanted to add a new item in the admin containing the field in question (I was using it to show ID fields).

The fix (for me) was to modify line 13 to read:

        if (self.original_object is not None) and (hasattr(self.original_object, '_meta')):

now it no longer throws the error for me.

#

graeme (on June 28, 2009):

I was getting errors when there was a null value in a foreign key (pointing to User).

Changing some lines in ModelLinkAdminFields fixed it:

    if hasattr(self, 'modellink'):
        for field_name in self.modellink:
            if field_name in form.base_fields:
                try:
                    y = getattr(obj, field_name, None)
                except:
                    y = None
                form.base_fields[field_name].widget = ModelLinkWidget(self.admin_site, y)

I am not sure this is the best only way, and only fields that had been filled in by django-evolution caused problems, so this probably will not affect everyone.

#

(Forgotten your password?)