﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
15424	readonly_fields in InlineModelAdmin looks up wrong callable	Mikhail Korobov	nobody	"my_app.models:
{{{#!python
from django.db import models

class Foo(models.Model):
    name = models.CharField(max_length=100)

class Bar(models.Model):
    foo = models.ForeignKey(Foo)

}}}

my_app.admin:
{{{#!python
from django.contrib import admin
from my_app import Foo, Bar

class BarInline(admin.TabularInline):
    model = Bar
    readonly_fields=['call_me']
    
    def call_me(self, obj):
        return 'BarInline'

class FooAdmin(admin.ModelAdmin):
    inlines = [BarInline]

    def call_me(self, obj):
        return 'FooAdmin'

admin.site.register(Foo, FooAdmin)

}}}

This will show {{{'FooAdmin'}}} as a 'call_me' value for each inline. If there is no 'call_me' method in FooAdmin, django ends with exception (example above is a simplified version of my setup, exception is from real project so model names don't match):

{{{
Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/admin/sales/position/2/

Django Version: 1.3 beta 1 SVN-15636
Python Version: 2.6.6
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'south',
 'info',
 'accounts',
 'sales',
 'debug_toolbar']
Installed Middleware:
['django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware']


Template error:
In template /Users/kmike/envs/tenders/src/django/django/contrib/admin/templates/admin/edit_inline/tabular.html, error at line 10
   Caught AttributeError while rendering: 'PositionAdmin' object has no attribute '__name__'
   1 : {% load i18n adminmedia admin_modify %}


   2 : <div class=""inline-group"" id=""{{ inline_admin_formset.formset.prefix }}-group"">


   3 :   <div class=""tabular inline-related {% if forloop.last %}last-related{% endif %}"">


   4 : {{ inline_admin_formset.formset.management_form }}


   5 : <fieldset class=""module"">


   6 :    <h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>


   7 :    {{ inline_admin_formset.formset.non_form_errors }}


   8 :    <table>


   9 :      <thead><tr>


   10 :       {% for field in inline_admin_formset.fields %} 


   11 :        {% if not field.widget.is_hidden %}


   12 :          <th{% if forloop.first %} colspan=""2""{% endif %}{% if field.required %} class=""required""{% endif %}>{{ field.label|capfirst }}</th>


   13 :        {% endif %}


   14 :      {% endfor %}


   15 :      {% if inline_admin_formset.formset.can_delete %}<th>{% trans ""Delete?"" %}</th>{% endif %}


   16 :      </tr></thead>


   17 : 


   18 :      <tbody>


   19 :      {% for inline_admin_form in inline_admin_formset %}


   20 :         {% if inline_admin_form.form.non_field_errors %}


Traceback:
File ""/Users/kmike/envs/tenders/src/django/django/core/handlers/base.py"" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File ""/Users/kmike/envs/tenders/src/django/django/contrib/admin/options.py"" in wrapper
  308.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File ""/Users/kmike/envs/tenders/src/django/django/utils/decorators.py"" in _wrapped_view
  93.                     response = view_func(request, *args, **kwargs)
File ""/Users/kmike/envs/tenders/src/django/django/views/decorators/cache.py"" in _wrapped_view_func
  79.         response = view_func(request, *args, **kwargs)
File ""/Users/kmike/envs/tenders/src/django/django/contrib/admin/sites.py"" in inner
  196.             return view(request, *args, **kwargs)
File ""/Users/kmike/envs/tenders/src/django/django/utils/decorators.py"" in _wrapper
  28.             return bound_func(*args, **kwargs)
File ""/Users/kmike/envs/tenders/src/django/django/utils/decorators.py"" in _wrapped_view
  93.                     response = view_func(request, *args, **kwargs)
File ""/Users/kmike/envs/tenders/src/django/django/utils/decorators.py"" in bound_func
  24.                 return func(self, *args2, **kwargs2)
File ""/Users/kmike/envs/tenders/src/django/django/db/transaction.py"" in inner
  217.                 res = func(*args, **kwargs)
File ""/Users/kmike/envs/tenders/src/django/django/contrib/admin/options.py"" in change_view
  1031.         return self.render_change_form(request, context, change=True, obj=obj)
File ""/Users/kmike/envs/tenders/src/django/django/contrib/admin/options.py"" in render_change_form
  709.         ], context, context_instance=context_instance)
File ""/Users/kmike/envs/tenders/src/django/django/shortcuts/__init__.py"" in render_to_response
  20.     return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
File ""/Users/kmike/envs/tenders/src/django/django/template/loader.py"" in render_to_string
  188.         return t.render(context_instance)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in render
  123.             return self._render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in _render
  117.         return self.nodelist.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in render
  744.                 bits.append(self.render_node(node, context))
File ""/Users/kmike/envs/tenders/src/django/django/template/debug.py"" in render_node
  73.             result = node.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/loader_tags.py"" in render
  127.         return compiled_parent._render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in _render
  117.         return self.nodelist.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in render
  744.                 bits.append(self.render_node(node, context))
File ""/Users/kmike/envs/tenders/src/django/django/template/debug.py"" in render_node
  73.             result = node.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/loader_tags.py"" in render
  127.         return compiled_parent._render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in _render
  117.         return self.nodelist.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in render
  744.                 bits.append(self.render_node(node, context))
File ""/Users/kmike/envs/tenders/src/django/django/template/debug.py"" in render_node
  73.             result = node.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/loader_tags.py"" in render
  64.             result = block.nodelist.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in render
  744.                 bits.append(self.render_node(node, context))
File ""/Users/kmike/envs/tenders/src/django/django/template/debug.py"" in render_node
  73.             result = node.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/defaulttags.py"" in render
  227.                 nodelist.append(node.render(context))
File ""/Users/kmike/envs/tenders/src/django/django/template/loader_tags.py"" in render
  170.             return self.render_template(template, context)
File ""/Users/kmike/envs/tenders/src/django/django/template/loader_tags.py"" in render_template
  141.         output = template.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in render
  123.             return self._render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in _render
  117.         return self.nodelist.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/base.py"" in render
  744.                 bits.append(self.render_node(node, context))
File ""/Users/kmike/envs/tenders/src/django/django/template/debug.py"" in render_node
  73.             result = node.render(context)
File ""/Users/kmike/envs/tenders/src/django/django/template/defaulttags.py"" in render
  190.             values = list(values)
File ""/Users/kmike/envs/tenders/src/django/django/contrib/admin/helpers.py"" in fields
  225.                     'label': label_for_field(field, self.opts.model, self.model_admin),
File ""/Users/kmike/envs/tenders/src/django/django/contrib/admin/util.py"" in label_for_field
  252.                     message += "" or %s"" % (model_admin.__name__,)

Exception Type: TemplateSyntaxError at /admin/sales/position/2/
Exception Value: Caught AttributeError while rendering: 'PositionAdmin' object has no attribute '__name__'

}}} 

 "		closed	contrib.admin	dev		fixed			Accepted	0	0	0	0	0	0
