mirror of
https://github.com/django-components/django-components.git
synced 2025-07-18 13:55:01 +00:00

* feat: on_render * docs: fix typos * refactor: fix linter errors * refactor: make `error` in on_render_after optional to fix benchmarks * refactor: benchmark attempt 2 * refactor: fix linter errors * refactor: fix formatting
229 lines
6.9 KiB
Markdown
229 lines
6.9 KiB
Markdown
As larger projects get more complex, it can be hard to debug issues. Django Components provides a number of tools and approaches that can help you with that.
|
|
|
|
## Component and slot highlighting
|
|
|
|
Django Components provides a visual debugging feature that helps you understand the structure and boundaries of your components and slots. When enabled, it adds a colored border and a label around each component and slot on your rendered page.
|
|
|
|
To enable component and slot highlighting for all components and slots, set `highlight_components` and `highlight_slots` to `True` in [extensions defaults](../../../reference/settings/#django_components.app_settings.ComponentsSettings.extensions_defaults) in your `settings.py` file:
|
|
|
|
```python
|
|
from django_components import ComponentsSettings
|
|
|
|
COMPONENTS = ComponentsSettings(
|
|
extensions_defaults={
|
|
"debug_highlight": {
|
|
"highlight_slots": True,
|
|
"highlight_components": True,
|
|
},
|
|
},
|
|
)
|
|
```
|
|
|
|
Alternatively, you can enable highlighting for specific components by setting `Component.DebugHighlight.highlight_components` to `True`:
|
|
|
|
```python
|
|
class MyComponent(Component):
|
|
class DebugHighlight:
|
|
highlight_components = True
|
|
highlight_slots = True
|
|
```
|
|
|
|
Components will be highlighted with a **blue** border and label:
|
|
|
|

|
|
|
|
While the slots will be highlighted with a **red** border and label:
|
|
|
|

|
|
|
|
!!! warning
|
|
|
|
Use this feature ONLY in during development. Do NOT use it in production.
|
|
|
|
## Component path in errors
|
|
|
|
When an error occurs, the error message will show the path to the component that
|
|
caused the error. E.g.
|
|
|
|
```
|
|
KeyError: "An error occured while rendering components MyPage > MyLayout > MyComponent > Childomponent(slot:content)
|
|
```
|
|
|
|
The error message contains also the slot paths, so if you have a template like this:
|
|
|
|
```django
|
|
{% component "my_page" %}
|
|
{% slot "content" %}
|
|
{% component "table" %}
|
|
{% slot "header" %}
|
|
{% component "table_header" %}
|
|
... {# ERROR HERE #}
|
|
{% endcomponent %}
|
|
{% endslot %}
|
|
{% endcomponent %}
|
|
{% endslot %}
|
|
{% endcomponent %}
|
|
```
|
|
|
|
Then the error message will show the path to the component that caused the error:
|
|
|
|
```
|
|
KeyError: "An error occured while rendering components my_page > layout > layout(slot:content) > my_page(slot:content) > table > table(slot:header) > table_header > table_header(slot:content)
|
|
```
|
|
|
|
## Debug and trace logging
|
|
|
|
Django components supports [logging with Django](https://docs.djangoproject.com/en/5.2/howto/logging/#logging-how-to).
|
|
|
|
To configure logging for Django components, set the `django_components` logger in
|
|
[`LOGGING`](https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-LOGGING)
|
|
in `settings.py` (below).
|
|
|
|
Also see the [`settings.py` file in sampleproject](https://github.com/django-components/django-components/blob/master/sampleproject/sampleproject/settings.py) for a real-life example.
|
|
|
|
```py
|
|
import logging
|
|
import sys
|
|
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': False,
|
|
"handlers": {
|
|
"console": {
|
|
'class': 'logging.StreamHandler',
|
|
'stream': sys.stdout,
|
|
},
|
|
},
|
|
"loggers": {
|
|
"django_components": {
|
|
"level": logging.DEBUG,
|
|
"handlers": ["console"],
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
!!! info
|
|
|
|
To set TRACE level, set `"level"` to `5`:
|
|
|
|
```py
|
|
LOGGING = {
|
|
"loggers": {
|
|
"django_components": {
|
|
"level": 5,
|
|
"handlers": ["console"],
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
### Logger levels
|
|
|
|
As of v0.126, django-components primarily uses these logger levels:
|
|
|
|
- `DEBUG`: Report on loading associated HTML / JS / CSS files, autodiscovery, etc.
|
|
- `TRACE`: Detailed interaction of components and slots. Logs when template tags,
|
|
components, and slots are started / ended rendering, and when a slot is filled.
|
|
|
|
## Slot origin
|
|
|
|
When you pass a slot fill to a Component, the component and slot names is remebered
|
|
on the slot object.
|
|
|
|
Thus, you can check where a slot was filled from by printing it out:
|
|
|
|
```python
|
|
class MyComponent(Component):
|
|
def on_render_before(self, context: Context, template: Optional[Template]):
|
|
print(self.slots)
|
|
```
|
|
|
|
might print:
|
|
|
|
```python
|
|
{
|
|
'content': <Slot component_name='layout' slot_name='content'>,
|
|
'header': <Slot component_name='my_page' slot_name='header'>,
|
|
'left_panel': <Slot component_name='layout' slot_name='left_panel'>,
|
|
}
|
|
```
|
|
|
|
## Agentic debugging
|
|
|
|
All the features above make django-components to work really well with coding AI agents
|
|
like Github Copilot or CursorAI.
|
|
|
|
To debug component rendering with LLMs, you want to provide the LLM with:
|
|
|
|
1. The components source code
|
|
2. The rendered output
|
|
3. As much additional context as possible
|
|
|
|
Your codebase already contains the components source code, but not the latter two.
|
|
|
|
### Providing rendered output
|
|
|
|
To provide the LLM with the rendered output, you can simply export the rendered output to a file.
|
|
|
|
```python
|
|
rendered = ProjectPage.render(...)
|
|
with open("result.html", "w") as f:
|
|
f.write(rendered)
|
|
```
|
|
|
|
If you're using `render_to_response`, access the output from the `HttpResponse` object:
|
|
|
|
```python
|
|
response = ProjectPage.render_to_response(...)
|
|
with open("result.html", "wb") as f:
|
|
f.write(response.content)
|
|
```
|
|
|
|
### Providing contextual logs
|
|
|
|
Next, we provide the agent with info on HOW we got the result that we have. We do so
|
|
by providing the agent with the trace-level logs.
|
|
|
|
In your `settings.py`, configure the trace-level logs to be written to the `django_components.log` file:
|
|
|
|
```python
|
|
LOGGING = {
|
|
"version": 1,
|
|
"disable_existing_loggers": False,
|
|
"handlers": {
|
|
"file": {
|
|
"class": "logging.FileHandler",
|
|
"filename": "django_components.log",
|
|
"mode": "w", # Overwrite the file each time
|
|
},
|
|
},
|
|
"loggers": {
|
|
"django_components": {
|
|
"level": 5,
|
|
"handlers": ["file"],
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
### Prompting the agent
|
|
|
|
Now, you can prompt the agent and include the trace log and the rendered output to guide the agent with debugging.
|
|
|
|
> I have a django-components (DJC) project. DJC is like if Vue or React component-based web development but made for Django ecosystem.
|
|
>
|
|
> In the view `project_view`, I am rendering the `ProjectPage` component. However, the output is not as expected.
|
|
> The output is missing the tabs.
|
|
>
|
|
> You have access to the full log trace in `django_components.log`.
|
|
>
|
|
> You can also see the rendered output in `result.html`.
|
|
>
|
|
> With this information, help me debug the issue.
|
|
>
|
|
> First, tell me what kind of info you would be looking for in the logs, and why (how it relates to understanding the cause of the bug).
|
|
>
|
|
> Then tell me if that info was there, and what the implications are.
|
|
>
|
|
> Finally, tell me what you would do to fix the issue.
|