#15424: readonly_fields in InlineModelAdmin looks up wrong callable
----------------------------------+-----------------------------------------
 Reporter:  kmike                 |          Owner:  nobody    
   Status:  new                   |      Milestone:            
Component:  django.contrib.admin  |        Version:  SVN       
 Keywords:                        |   Triage Stage:  Unreviewed
Has patch:  0                     |  
----------------------------------+-----------------------------------------
 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__'

 }}}

-- 
Ticket URL: <http://code.djangoproject.com/ticket/15424>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to