Opened 18 years ago
Closed 18 years ago
#7034 closed (invalid)
get_nodes_by_type() fails if nodelist = None
| Reported by: | kilian | Owned by: | nobody |
|---|---|---|---|
| Component: | Template system | Version: | dev |
| Severity: | Keywords: | inheritance nodelist | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Using Jacob's Google Charts templatetags, I've encountered a strange bug in the template systems. The {% axis "bottom" hide %} directive works fine in a stand-alone template, but fails if the template extends an other template.
For instance, the following template (straight from the examples):
{% extends "base.html" %}
{% load charts %}
{% chart %}
{% chart-size "300x200" %}
{% chart-type "line" %}
{% chart-data "1,5,2,10" %}
{% axis "left" %}
{% axis-range "0" "10" %}
{% endaxis %}
{% axis "left" hide %}
{% endchart %}
raises the following exception:
File "/home/kilian/django/django/template/__init__.py" in get_nodes_by_type 762. nodes.extend(node.get_nodes_by_type(nodetype)) File "/home/kilian/django/django/template/__init__.py" in get_nodes_by_type 741. nodes.extend(self.nodelist.get_nodes_by_type(nodetype)) Exception Type: AttributeError at /test/ Exception Value: 'NoneType' object has no attribute 'get_nodes_by_type'
If the {% extends "base.html" %} is removed from the template, then it works fine, and no exception is raised. It looks like, for some reason, the parsing of the {% axis "left" hide %} tag generates a Node whose nodelist attribute is not a NodeList object. neither a list, but rather None.
The attached patch proposes a solution to take care of this case.
Attachments (1)
Change History (4)
by , 18 years ago
| Attachment: | django.nodelist.patch added |
|---|
follow-up: 2 comment:1 by , 18 years ago
comment:2 by , 18 years ago
Replying to mtredinnick:
I'm not sure your patch is really fixing the right problem. It's probably quite reasonable for us to assume nodelist is an actual list of nodes -- something we can iterate over. So if this is a real bug, it lies in the template tag causing it.
I was not sure either. I've looked in the template tag definition, but couldn't find any problem with it. If you want to take a look, maybe you'll find something I missed.
If you can repeat this problem with a proper template (all code outside the extends tag must lie inside
{% block %}...{% endblock %}sections),
I omitted the {% block %}...{% endblock %} tags to keep things short (which I shouldn't have), but I can confirm the same behavior with the following template (where {% block content %} is defined in the "base.html" template):
{% extends "base.html" %}
{% block content %}
{% load charts %}
{% chart %}
{% chart-size "300x200" %}
{% chart-type "line" %}
{% chart-data "1,5,2,10" %}
{% axis "left" %}
{% axis-range "0" "10" %}
{% endaxis %}
{% axis "left" hide %}
{% endchart %}
{% endblock %}
However, if the {% chart %}...{% end chart %} block is the only content of the template, it works fine.
then this is a bug (although in that case we can probably bounce it to google-charts project for fixing).
I'm afraid there's no official way to report bugs to that project, except sending a direct email to Jacob, probably.
comment:3 by , 18 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
Actually, after further inspection, it indeed seems that the bug lies in the charts templatetag definition:
class AxisNode(template.Node):
def __init__(self, side, nodelist=None):
self.nodelist = nodelist
...
When the {% axis "..." hide %} tag is found, an AxisNode instance is created, with no nodelist argument. Hence self.nodelist gets the default None value, and the "'NoneType' object has no attribute 'get_nodes_by_type'" exception is raised while parsing it.
So that's not a Django bug after all. I'll send a patch to the google-charts project. Sorry for the noise. :)
I'm not sure your patch is really fixing the right problem. It's probably quite reasonable for us to assume nodelist is an actual list of nodes -- something we can iterate over. So if this is a real bug, it lies in the template tag causing it.
However, I suspect the problem actually lies elsewhere: the example you give in the description is not a valid template. If you extend another template you can only override the blocks from the parent template. Anything outside a block in the child template is invalid and so unexpected things will happen (as exhibited here, I suspect).
If you can repeat this problem with a proper template (all code outside the extends tag must lie inside
{% block %}...{% endblock %}sections), then this is a bug (although in that case we can probably bounce it to google-charts project for fixing). If you can't repeat it in that case, it's not a bug since your template is invalid.