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. autocompleter with database query by bbolli 6 years, 9 months ago
  2. Javascript Chain Select Widget by ogo 5 years, 10 months ago
  3. Select or Create widget by Naster 1 month, 3 weeks ago
  4. Read only form & model field by StanislavKraev 2 years, 9 months ago
  5. Querying on existence of a relationship by ubernostrum 6 years, 8 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?)