Opened 16 years ago

Closed 13 years ago

Last modified 13 years ago

#11079 closed Bug (fixed)

Multi-table inheritance subclasses cannot be proxied

Reported by: George Song Owned by: nobody
Component: Database layer (models, ORM) Version: 1.0
Severity: Normal Keywords: model proxy multi-table inheritance
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Creating a proxy model for a multi-table inherited subclass fails.

class Place(models.Model):
    name = models.CharField(max_length=50)

class Restaurant(Place):
    genre = models.CharField(max_length=50)

class PizzaJoint(Restaurant):
    class Meta:
        proxy = True

>>> from proxy.models import Restaurant, PizzaJoint
>>> Restaurant.objects.create(name='Greasy Pizza', genre='pizza')
<Restaurant: Restaurant object>
>>> Restaurant.objects.all()
[<Restaurant: Restaurant object>]
>>> PizzaJoint.objects.all()
[]

Also when accessing admin/proxy/pizzajoint/, you get the following stack trace:

Template error:
In template e:\lehrhaus\django\django\contrib\admin\templates\admin\change_list.html, error at line 78
   Caught an exception while rendering: 'NoneType' object has no attribute 'column'
   68 :         {% endif %}
   69 :       {% endblock %}
   70 :       
   71 :       <form action="" method="post"{% if cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %}>
   72 :       {% if cl.formset %}
   73 :         {{ cl.formset.management_form }}
   74 :       {% endif %}
   75 : 
   76 :       {% block result_list %}
   77 :           {% if action_form and actions_on_top and cl.full_result_count %}{% admin_actions %}{% endif %}
   78 :            {% result_list cl %} 
   79 :           {% if action_form and actions_on_bottom and cl.full_result_count %}{% admin_actions %}{% endif %}
   80 :       {% endblock %}
   81 :       {% block pagination %}{% pagination cl %}{% endblock %}
   82 :       </form>
   83 :     </div>
   84 :   </div>
   85 : {% endblock %}
   86 : 

Traceback:
File "E:\lehrhaus\django\django\core\handlers\base.py" in get_response
  92.                 response = callback(request, *callback_args, **callback_kwargs)
File "E:\lehrhaus\django\django\contrib\admin\options.py" in wrapper
  226.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "E:\lehrhaus\django\django\contrib\admin\sites.py" in inner
  184.             return view(request, *args, **kwargs)
File "E:\lehrhaus\django\django\contrib\admin\options.py" in changelist_view
  984.         ], context, context_instance=template.RequestContext(request))
File "E:\lehrhaus\django\django\shortcuts\__init__.py" in render_to_response
  20.     return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
File "E:\lehrhaus\django\django\template\loader.py" in render_to_string
  108.     return t.render(context_instance)
File "E:\lehrhaus\django\django\template\__init__.py" in render
  178.         return self.nodelist.render(context)
File "E:\lehrhaus\django\django\template\__init__.py" in render
  779.                 bits.append(self.render_node(node, context))
File "E:\lehrhaus\django\django\template\debug.py" in render_node
  71.             result = node.render(context)
File "E:\lehrhaus\django\django\template\loader_tags.py" in render
  97.         return compiled_parent.render(context)
File "E:\lehrhaus\django\django\template\__init__.py" in render
  178.         return self.nodelist.render(context)
File "E:\lehrhaus\django\django\template\__init__.py" in render
  779.                 bits.append(self.render_node(node, context))
File "E:\lehrhaus\django\django\template\debug.py" in render_node
  71.             result = node.render(context)
File "E:\lehrhaus\django\django\template\loader_tags.py" in render
  97.         return compiled_parent.render(context)
File "E:\lehrhaus\django\django\template\__init__.py" in render
  178.         return self.nodelist.render(context)
File "E:\lehrhaus\django\django\template\__init__.py" in render
  779.                 bits.append(self.render_node(node, context))
File "E:\lehrhaus\django\django\template\debug.py" in render_node
  71.             result = node.render(context)
File "E:\lehrhaus\django\django\template\loader_tags.py" in render
  24.         result = self.nodelist.render(context)
File "E:\lehrhaus\django\django\template\__init__.py" in render
  779.                 bits.append(self.render_node(node, context))
File "E:\lehrhaus\django\django\template\debug.py" in render_node
  71.             result = node.render(context)
File "E:\lehrhaus\django\django\template\loader_tags.py" in render
  24.         result = self.nodelist.render(context)
File "E:\lehrhaus\django\django\template\__init__.py" in render
  779.                 bits.append(self.render_node(node, context))
File "E:\lehrhaus\django\django\template\debug.py" in render_node
  81.             raise wrapped

Exception Type: TemplateSyntaxError at /admin/proxy/pizzajoint/
Exception Value: Caught an exception while rendering: 'NoneType' object has no attribute 'column'

Original Traceback (most recent call last):
  File "E:\lehrhaus\django\django\template\debug.py", line 71, in render_node
    result = node.render(context)
  File "E:\lehrhaus\django\django\template\__init__.py", line 936, in render
    dict = func(*args)
  File "E:\lehrhaus\django\django\contrib\admin\templatetags\admin_list.py", line 251, in result_list
    return {'cl': cl,
  File "E:\lehrhaus\django\django\contrib\admin\templatetags\admin_list.py", line 247, in results
    for res in cl.result_list:
  File "E:\lehrhaus\django\django\db\models\query.py", line 93, in _result_iter
    self._fill_cache()
  File "E:\lehrhaus\django\django\db\models\query.py", line 660, in _fill_cache
    self._result_cache.append(self._iter.next())
  File "E:\lehrhaus\django\django\db\models\query.py", line 207, in iterator
    for row in self.query.results_iter():
  File "E:\lehrhaus\django\django\db\models\sql\query.py", line 287, in results_iter
    for rows in self.execute_sql(MULTI):
  File "E:\lehrhaus\django\django\db\models\sql\query.py", line 2336, in execute_sql
    sql, params = self.as_sql()
  File "E:\lehrhaus\django\django\db\models\sql\query.py", line 395, in as_sql
    self.pre_sql_setup()
  File "E:\lehrhaus\django\django\db\models\sql\query.py", line 587, in pre_sql_setup
    self.setup_inherited_models()
  File "E:\lehrhaus\django\django\db\models\sql\query.py", line 1311, in setup_inherited_models
    seen[model] = self.join((root_alias, model._meta.db_table,
AttributeError: 'NoneType' object has no attribute 'column'

Change History (7)

comment:1 by George Song, 16 years ago

Summary: Multi-table inheritance subclassed cannot be proxiedMulti-table inheritance subclasses cannot be proxied

comment:2 by Alex Gaynor, 15 years ago

Triage Stage: UnreviewedAccepted

comment:3 by Julien Phalip, 14 years ago

Severity: Normal
Type: Bug

comment:4 by Aymeric Augustin, 13 years ago

UI/UX: unset

Change UI/UX from NULL to False.

comment:5 by Aymeric Augustin, 13 years ago

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:6 by Simon Charette, 13 years ago

Resolution: fixed
Status: newclosed
Version: SVN1.3

Cannot reproduce on django 1.4

>>> import django
>>> django.VERSION
(1, 4, 0, 'final', 0)
>>> from ticket_11079.models import Restaurant, PizzaJoint
>>> Restaurant.objects.create(name='Greasy Pizza', genre='pizza')
<Restaurant: Restaurant object>
>>> Restaurant.objects.all()
[<Restaurant: Restaurant object>]
>>> PizzaJoint.objects.all()
[<PizzaJoint: PizzaJoint object>]

django 1.3.1

>>> import django
>>> django.VERSION
(1, 3, 1, 'final', 0)
>>> from ticket_11079.models import Restaurant, PizzaJoint
>>> Restaurant.objects.create(name='Greasy Pizza', genre='pizza')
<Restaurant: Restaurant object>
>>> Restaurant.objects.all()
[<Restaurant: Restaurant object>]
>>> PizzaJoint.objects.all()
[<PizzaJoint: PizzaJoint object>]

And django 1.2.7

>>> import django
>>> django.VERSION
(1, 2, 7, 'final', 0)
>>> from ticket_11079.models import Restaurant, PizzaJoint
>>> Restaurant.objects.create(name='Greasy Pizza', genre='pizza')
<Restaurant: Restaurant object>
>>> Restaurant.objects.all()
[<Restaurant: Restaurant object>]
>>> PizzaJoint.objects.all()
[<PizzaJoint: PizzaJoint object>]

At the time this ticket was created (05/12/09) django 1.1 was not even released. I cannot find which commit fixed this issue but since it has been fixed in trunk for about 3 years I'm marking this ticket as fixed.

Last edited 13 years ago by Simon Charette (previous) (diff)

comment:7 by Simon Charette, 13 years ago

Version: 1.31.0
Note: See TracTickets for help on using tickets.
Back to Top