Skip to content

KeyError rendering component with nested slots #698

@larsent

Description

@larsent

Hi, I'm working on upgrading from 0.50 to 0.101. I think I have an example using nested slots that worked in 0.50 but doesn't work in 0.101. I read the changelog, but apologies if I missed something in there that might explain this.

I put together a minimal repo to reproduce this: https://github.com/larsent/django-components-nested-slots-poc. You should be able to just change the django-components version in requirements.txt between 0.50 and 0.101 within that same repo (in my real project I have followed further upgrade steps, e.g. around settings).

You can see my nested component example here. I'm then rendering that component multiple times here, each filling a different level in the nested hierarchy.

In 0.50, I'm able to fill any or none of those slots. Unfilled slots retain their defaults set in the component template.

Screenshot 2024-10-07 at 2 05 23 PM

The divs with the blue background have been replaced by filling single slots within the nested hierarchy. This works as expected.

However, in 0.101, I get a KeyError: ""An error occured while rendering component 'example':\nKeyError('0009')"

Full Traceback

Environment:


Request Method: GET
Request URL: http://localhost:8001/

Django Version: 5.0.8
Python Version: 3.11.9
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django_components']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template /Users/tom/projects/django-components-nested-slots-poc/templates/home.html, error at line 5
   An error occured while rendering component 'example':
KeyError('0009')
   1 : {% extends 'base.html' %} 
   2 : {% block content %} 
   3 : 
   4 : <h2>Nothing Filled</h2>
   5 :  {% component 'example' %}  
   6 : {% endcomponent %} 
   7 : 
   8 : <h2>Override Wrapper</h2>
   9 : {% component 'example' %} 
   10 :     {% fill 'wrapper' %}
   11 :     <div style="background: blue; color:white; padding:10px">
   12 :         Entire Wrapper Replaced
   13 :     </div>
   14 :     {% endfill %}
   15 : {% endcomponent %} 


Traceback (most recent call last):
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django_components/component.py", line 576, in _render
    return self._render_impl(context, args, kwargs, slots, escape_slots_content)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django_components/component.py", line 675, in _render_impl
    rendered_component = template.render(context)
                         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django_components/component.py", line 927, in _template_render
    return self._render(context, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 961, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django_components/slots.py", line 228, in render
    output = slot_fill.content_func(used_ctx, kwargs, slot_ref)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django_components/slots.py", line 729, in render_func
    return nodelist.render(ctx)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 961, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django_components/slots.py", line 183, in render
    slot_fill = slots[self.node_id]
                ^^^^^^^^^^^^^^^^^^^

The above exception ('0009') was the direct cause of the following exception:
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/poc/views.py", line 5, in home
    return render(request, "home.html")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/shortcuts.py", line 25, in render
    content = loader.render_to_string(template_name, context, request, using=using)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 171, in render
    return self._render(context)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 961, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/loader_tags.py", line 159, in render
    return compiled_parent._render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 961, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/loader_tags.py", line 65, in render
    result = block.nodelist.render(context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django/template/base.py", line 961, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django_components/component.py", line 875, in render
    output = component._render(
             
  File "/Users/tom/projects/django-components-nested-slots-poc/venv/lib/python3.11/site-packages/django_components/component.py", line 578, in _render
    raise type(err)(f"An error occured while rendering component '{self.name}':\n{repr(err)}") from err
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: KeyError at /
Exception Value: "An error occured while rendering component 'example':\nKeyError('0009')"

In raising this issue, I'm hoping to get feedback on whether this usage is expected to work on 0.50, 0.101, both, or neither (perhaps it only works accidentally on 0.50). Thanks for all your work on this great project!

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions