Opened 17 years ago
Closed 17 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 , 17 years ago
Attachment: | django.nodelist.patch added |
---|
follow-up: 2 comment:1 by , 17 years ago
comment:2 by , 17 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 , 17 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.