mirror of
https://github.com/django-components/django-components.git
synced 2025-08-31 11:17:21 +00:00
refactor: Instantiate component when rendering, and remove metadata stack (#1212)
* refactor: Instantiate component when rendering, and remove metadata stack * refactor: update test * refactor: fix linter errors * docs: remove example from changelog
This commit is contained in:
parent
2e08af9a13
commit
bae0f28813
33 changed files with 1123 additions and 707 deletions
|
@ -52,6 +52,12 @@ See the full list in [Extension Hooks Reference](../../../reference/extension_ho
|
|||
Each extension has a corresponding nested class within the [`Component`](../../../reference/api#django_components.Component) class. These allow
|
||||
to configure the extensions on a per-component basis.
|
||||
|
||||
E.g.:
|
||||
|
||||
- `"view"` extension -> [`Component.View`](../../../reference/api#django_components.Component.View)
|
||||
- `"cache"` extension -> [`Component.Cache`](../../../reference/api#django_components.Component.Cache)
|
||||
- `"defaults"` extension -> [`Component.Defaults`](../../../reference/api#django_components.Component.Defaults)
|
||||
|
||||
!!! note
|
||||
|
||||
**Accessing the component instance from inside the nested classes:**
|
||||
|
@ -61,10 +67,10 @@ to configure the extensions on a per-component basis.
|
|||
|
||||
```python
|
||||
class MyTable(Component):
|
||||
class View:
|
||||
class MyExtension:
|
||||
def get(self, request):
|
||||
# `self.component` points to the instance of `MyTable` Component.
|
||||
return self.component.get(request)
|
||||
return self.component.render_to_response(request=request)
|
||||
```
|
||||
|
||||
### Example: Component as View
|
||||
|
@ -78,10 +84,14 @@ You can override the `get()`, `post()`, etc methods to customize the behavior of
|
|||
class MyTable(Component):
|
||||
class View:
|
||||
def get(self, request):
|
||||
return self.component.get(request)
|
||||
# TO BE IMPLEMENTED BY USER
|
||||
# return self.component_cls.render_to_response(request=request)
|
||||
raise NotImplementedError("You must implement the `get` method.")
|
||||
|
||||
def post(self, request):
|
||||
return self.component.post(request)
|
||||
# TO BE IMPLEMENTED BY USER
|
||||
# return self.component_cls.render_to_response(request=request)
|
||||
raise NotImplementedError("You must implement the `post` method.")
|
||||
|
||||
...
|
||||
```
|
||||
|
@ -97,12 +107,12 @@ JSON file from the component.
|
|||
class MyTable(Component):
|
||||
class Storybook:
|
||||
def title(self):
|
||||
return self.component.__class__.__name__
|
||||
return self.component_cls.__name__
|
||||
|
||||
def parameters(self) -> Parameters:
|
||||
return {
|
||||
"server": {
|
||||
"id": self.component.__class__.__name__,
|
||||
"id": self.component_cls.__name__,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,10 +218,14 @@ class ViewExtension(ComponentExtension):
|
|||
# The default behavior of the `View` extension class.
|
||||
class ExtensionClass(ComponentExtension.ExtensionClass):
|
||||
def get(self, request):
|
||||
return self.component.get(request)
|
||||
# TO BE IMPLEMENTED BY USER
|
||||
# return self.component_cls.render_to_response(request=request)
|
||||
raise NotImplementedError("You must implement the `get` method.")
|
||||
|
||||
def post(self, request):
|
||||
return self.component.post(request)
|
||||
# TO BE IMPLEMENTED BY USER
|
||||
# return self.component_cls.render_to_response(request=request)
|
||||
raise NotImplementedError("You must implement the `post` method.")
|
||||
|
||||
...
|
||||
```
|
||||
|
|
|
@ -136,7 +136,7 @@ class MyPage(Component):
|
|||
|
||||
class View:
|
||||
def get(self, request):
|
||||
return self.component.render_to_response(request=request)
|
||||
return self.component_cls.render_to_response(request=request)
|
||||
```
|
||||
|
||||
### 2. Define fragment HTML
|
||||
|
@ -166,7 +166,7 @@ class Frag(Component):
|
|||
|
||||
class View:
|
||||
def get(self, request):
|
||||
return self.component.render_to_response(
|
||||
return self.component_cls.render_to_response(
|
||||
request=request,
|
||||
# IMPORTANT: Don't forget `deps_strategy="fragment"`
|
||||
deps_strategy="fragment",
|
||||
|
@ -228,7 +228,7 @@ class MyPage(Component):
|
|||
|
||||
class View:
|
||||
def get(self, request):
|
||||
return self.component.render_to_response(request=request)
|
||||
return self.component_cls.render_to_response(request=request)
|
||||
```
|
||||
|
||||
### 2. Define fragment HTML
|
||||
|
@ -271,7 +271,7 @@ class Frag(Component):
|
|||
|
||||
class View:
|
||||
def get(self, request):
|
||||
return self.component.render_to_response(
|
||||
return self.component_cls.render_to_response(
|
||||
request=request,
|
||||
# IMPORTANT: Don't forget `deps_strategy="fragment"`
|
||||
deps_strategy="fragment",
|
||||
|
@ -332,7 +332,7 @@ class MyPage(Component):
|
|||
|
||||
class View:
|
||||
def get(self, request):
|
||||
return self.component.render_to_response(request=request)
|
||||
return self.component_cls.render_to_response(request=request)
|
||||
```
|
||||
|
||||
### 2. Define fragment HTML
|
||||
|
@ -362,7 +362,7 @@ class Frag(Component):
|
|||
|
||||
class View:
|
||||
def get(self, request):
|
||||
return self.component.render_to_response(
|
||||
return self.component_cls.render_to_response(
|
||||
request=request,
|
||||
# IMPORTANT: Don't forget `deps_strategy="fragment"`
|
||||
deps_strategy="fragment",
|
||||
|
|
|
@ -110,6 +110,6 @@ from django_components.testing import djc_test
|
|||
)
|
||||
)
|
||||
def test_context_behavior(components_settings):
|
||||
rendered = MyComponent().render()
|
||||
rendered = MyComponent.render()
|
||||
...
|
||||
```
|
||||
|
|
|
@ -81,9 +81,9 @@ class Calendar(Component):
|
|||
|
||||
This is deprecated from v0.137 onwards, and will be removed in v1.0.
|
||||
|
||||
### Acccessing component instance
|
||||
### Acccessing component class
|
||||
|
||||
You can access the component instance from within the View methods by using the [`View.component`](../../../reference/api#django_components.ComponentView.component) attribute:
|
||||
You can access the component class from within the View methods by using the [`View.component_cls`](../../../reference/api#django_components.ComponentView.component_cls) attribute:
|
||||
|
||||
```py
|
||||
class Calendar(Component):
|
||||
|
@ -91,20 +91,9 @@ class Calendar(Component):
|
|||
|
||||
class View:
|
||||
def get(self, request):
|
||||
return self.component.render_to_response(request=request)
|
||||
return self.component_cls.render_to_response(request=request)
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
The [`View.component`](../../../reference/api#django_components.ComponentView.component) instance is a dummy instance created solely for the View methods.
|
||||
|
||||
It is the same as if you instantiated the component class directly:
|
||||
|
||||
```py
|
||||
component = Calendar()
|
||||
component.render_to_response(request=request)
|
||||
```
|
||||
|
||||
## Register URLs manually
|
||||
|
||||
To register the component as a route / endpoint in Django, add an entry to your
|
||||
|
@ -134,7 +123,7 @@ class MyComponent(Component):
|
|||
public = True
|
||||
|
||||
def get(self, request):
|
||||
return self.component.render_to_response(request=request)
|
||||
return self.component_cls.render_to_response(request=request)
|
||||
...
|
||||
```
|
||||
|
||||
|
|
|
@ -260,7 +260,7 @@ This includes:
|
|||
- [`input.type`](../../../reference/api/#django_components.ComponentInput.type) - The type of the component (document, fragment)
|
||||
- [`input.render_dependencies`](../../../reference/api/#django_components.ComponentInput.render_dependencies) - Whether to render dependencies (CSS, JS)
|
||||
|
||||
For more details, see [Component inputs](../render_api/#component-inputs).
|
||||
For more details, see [Component inputs](../render_api/#other-inputs).
|
||||
|
||||
```python
|
||||
class ProfileCard(Component):
|
||||
|
@ -343,16 +343,20 @@ class ProfileCard(Component):
|
|||
|
||||
## Accessing Render API
|
||||
|
||||
All three data methods have access to the Component's [Render API](./render_api.md), which includes:
|
||||
All three data methods have access to the Component's [Render API](../render_api), which includes:
|
||||
|
||||
- [`self.args`](./render_api/#args) - The positional arguments for the current render call
|
||||
- [`self.kwargs`](./render_api/#kwargs) - The keyword arguments for the current render call
|
||||
- [`self.slots`](./render_api/#slots) - The slots for the current render call
|
||||
- [`self.input`](./render_api/#component-inputs) - All the component inputs
|
||||
- [`self.id`](./render_api/#component-id) - The unique ID for the current render call
|
||||
- [`self.request`](./render_api/#request-object-and-context-processors) - The request object (if available)
|
||||
- [`self.context_processors_data`](./render_api/#request-object-and-context-processors) - Data from Django's context processors (if request is available)
|
||||
- [`self.inject()`](./render_api/#provide-inject) - Inject data into the component
|
||||
- [`self.args`](../render_api/#args) - The positional arguments for the current render call
|
||||
- [`self.kwargs`](../render_api/#kwargs) - The keyword arguments for the current render call
|
||||
- [`self.slots`](../render_api/#slots) - The slots for the current render call
|
||||
- [`self.context`](../render_api/#context) - The context for the current render call
|
||||
- [`self.input`](../render_api/#other-inputs) - All the component inputs
|
||||
- [`self.id`](../render_api/#component-id) - The unique ID for the current render call
|
||||
- [`self.request`](../render_api/#request-and-context-processors) - The request object
|
||||
- [`self.context_processors_data`](../render_api/#request-and-context-processors) - Data from Django's context processors
|
||||
- [`self.inject()`](../render_api/#provide-inject) - Inject data into the component
|
||||
- [`self.registry`](../render_api/#template-tag-metadata) - The [`ComponentRegistry`](../../../reference/api/#django_components.ComponentRegistry) instance
|
||||
- [`self.registered_name`](../render_api/#template-tag-metadata) - The name under which the component was registered
|
||||
- [`self.outer_context`](../render_api/#template-tag-metadata) - The context outside of the [`{% component %}`](../../../reference/template_tags#component) tag
|
||||
|
||||
## Type hints
|
||||
|
||||
|
|
|
@ -12,10 +12,6 @@ Render API is available inside these [`Component`](../../../reference/api#django
|
|||
- [`on_render_before()`](../../../reference/api#django_components.Component.on_render_before)
|
||||
- [`on_render_after()`](../../../reference/api#django_components.Component.on_render_after)
|
||||
|
||||
!!! note
|
||||
|
||||
If you try to access the Render API outside of these methods, you will get a `RuntimeError`.
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
|
@ -46,16 +42,31 @@ rendered = Table.render(
|
|||
|
||||
The Render API includes:
|
||||
|
||||
- [`self.args`](../render_api/#args) - The positional arguments for the current render call
|
||||
- [`self.kwargs`](../render_api/#kwargs) - The keyword arguments for the current render call
|
||||
- [`self.slots`](../render_api/#slots) - The slots for the current render call
|
||||
- [`self.input`](../render_api/#component-inputs) - All the component inputs
|
||||
- [`self.id`](../render_api/#component-id) - The unique ID for the current render call
|
||||
- [`self.request`](../render_api/#request-object-and-context-processors) - The request object (if available)
|
||||
- [`self.context_processors_data`](../render_api/#request-object-and-context-processors) - Data from Django's context processors (if request is available)
|
||||
- [`self.inject()`](../render_api/#provide-inject) - Inject data into the component
|
||||
- Component inputs:
|
||||
- [`self.args`](../render_api/#args) - The positional arguments for the current render call
|
||||
- [`self.kwargs`](../render_api/#kwargs) - The keyword arguments for the current render call
|
||||
- [`self.slots`](../render_api/#slots) - The slots for the current render call
|
||||
- [`self.context`](../render_api/#context) - The context for the current render call
|
||||
- [`self.input`](../render_api/#other-inputs) - All the component inputs
|
||||
|
||||
## Args
|
||||
- Request-related:
|
||||
- [`self.request`](../render_api/#request-and-context-processors) - The request object (if available)
|
||||
- [`self.context_processors_data`](../render_api/#request-and-context-processors) - Data from Django's context processors
|
||||
|
||||
- Provide / inject:
|
||||
- [`self.inject()`](../render_api/#provide-inject) - Inject data into the component
|
||||
|
||||
- Template tag metadata:
|
||||
- [`self.registry`](../render_api/#template-tag-metadata) - The [`ComponentRegistry`](../../../reference/api/#django_components.ComponentRegistry) instance
|
||||
- [`self.registered_name`](../render_api/#template-tag-metadata) - The name under which the component was registered
|
||||
- [`self.outer_context`](../render_api/#template-tag-metadata) - The context outside of the [`{% component %}`](../../../reference/template_tags#component) tag
|
||||
|
||||
- Other metadata:
|
||||
- [`self.id`](../render_api/#component-id) - The unique ID for the current render call
|
||||
|
||||
## Component inputs
|
||||
|
||||
### Args
|
||||
|
||||
The `args` argument as passed to
|
||||
[`Component.get_template_data()`](../../../reference/api/#django_components.Component.get_template_data).
|
||||
|
@ -65,8 +76,6 @@ then the [`Component.args`](../../../reference/api/#django_components.Component.
|
|||
|
||||
Otherwise, `args` will be a plain list.
|
||||
|
||||
Raises `RuntimeError` if accessed outside of rendering execution.
|
||||
|
||||
**Example:**
|
||||
|
||||
With `Args` class:
|
||||
|
@ -99,7 +108,7 @@ class Table(Component):
|
|||
assert self.args[1] == 10
|
||||
```
|
||||
|
||||
## Kwargs
|
||||
### Kwargs
|
||||
|
||||
The `kwargs` argument as passed to
|
||||
[`Component.get_template_data()`](../../../reference/api/#django_components.Component.get_template_data).
|
||||
|
@ -109,8 +118,6 @@ then the [`Component.kwargs`](../../../reference/api/#django_components.Componen
|
|||
|
||||
Otherwise, `kwargs` will be a plain dictionary.
|
||||
|
||||
Raises `RuntimeError` if accessed outside of rendering execution.
|
||||
|
||||
**Example:**
|
||||
|
||||
With `Kwargs` class:
|
||||
|
@ -143,7 +150,7 @@ class Table(Component):
|
|||
assert self.kwargs["per_page"] == 10
|
||||
```
|
||||
|
||||
## Slots
|
||||
### Slots
|
||||
|
||||
The `slots` argument as passed to
|
||||
[`Component.get_template_data()`](../../../reference/api/#django_components.Component.get_template_data).
|
||||
|
@ -153,8 +160,6 @@ then the [`Component.slots`](../../../reference/api/#django_components.Component
|
|||
|
||||
Otherwise, `slots` will be a plain dictionary.
|
||||
|
||||
Raises `RuntimeError` if accessed outside of rendering execution.
|
||||
|
||||
**Example:**
|
||||
|
||||
With `Slots` class:
|
||||
|
@ -190,7 +195,27 @@ class Table(Component):
|
|||
assert isinstance(self.slots["footer"], Slot)
|
||||
```
|
||||
|
||||
## Component inputs
|
||||
### Context
|
||||
|
||||
The `context` argument as passed to
|
||||
[`Component.get_template_data()`](../../../reference/api/#django_components.Component.get_template_data).
|
||||
|
||||
This is Django's [Context](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.Context)
|
||||
with which the component template is rendered.
|
||||
|
||||
If the root component or template was rendered with
|
||||
[`RequestContext`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.RequestContext)
|
||||
then this will be an instance of `RequestContext`.
|
||||
|
||||
Whether the context variables defined in `context` are available to the template depends on the
|
||||
[context behavior mode](../../../reference/settings#django_components.app_settings.ComponentsSettings.context_behavior):
|
||||
|
||||
- In `"django"` context behavior mode, the template will have access to the keys of this context.
|
||||
|
||||
- In `"isolated"` context behavior mode, the template will NOT have access to this context,
|
||||
and data MUST be passed via component's args and kwargs.
|
||||
|
||||
### Other inputs
|
||||
|
||||
You can access the most important inputs via [`self.args`](../render_api/#args),
|
||||
[`self.kwargs`](../render_api/#kwargs),
|
||||
|
@ -255,7 +280,7 @@ class Table(Component):
|
|||
assert self.id == "c1A2b3c"
|
||||
```
|
||||
|
||||
## Request object and context processors
|
||||
## Request and context processors
|
||||
|
||||
Components have access to the request object and context processors data if the component was:
|
||||
|
||||
|
@ -306,3 +331,32 @@ class Table(Component):
|
|||
data = self.inject("some_data")
|
||||
assert data.some_data == "some_data"
|
||||
```
|
||||
|
||||
## Template tag metadata
|
||||
|
||||
If the component is rendered with [`{% component %}`](../../../reference/template_tags#component) template tag,
|
||||
the following metadata is available:
|
||||
|
||||
- [`self.registry`](../../../reference/api/#django_components.Component.registry) - The [`ComponentRegistry`](../../../reference/api/#django_components.ComponentRegistry) instance
|
||||
that was used to render the component
|
||||
- [`self.registered_name`](../../../reference/api/#django_components.Component.registered_name) - The name under which the component was registered
|
||||
- [`self.outer_context`](../../../reference/api/#django_components.Component.outer_context) - The context outside of the [`{% component %}`](../../../reference/template_tags#component) tag
|
||||
|
||||
```django
|
||||
{% with abc=123 %}
|
||||
{{ abc }} {# <--- This is in outer context #}
|
||||
{% component "my_component" / %}
|
||||
{% endwith %}
|
||||
```
|
||||
|
||||
You can use these to check whether the component was rendered inside a template with [`{% component %}`](../../../reference/template_tags#component) tag
|
||||
or in Python with [`Component.render()`](../../../reference/api/#django_components.Component.render).
|
||||
|
||||
```python
|
||||
class MyComponent(Component):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
if self.registered_name is None:
|
||||
# Do something for the render() function
|
||||
else:
|
||||
# Do something for the {% component %} template tag
|
||||
```
|
||||
|
|
|
@ -246,7 +246,6 @@ Button.render(
|
|||
- `context` - Django context for rendering (can be a dictionary or a `Context` object)
|
||||
- `deps_strategy` - [Dependencies rendering strategy](#dependencies-rendering) (default: `"document"`)
|
||||
- `request` - [HTTP request object](../http_request), used for context processors (optional)
|
||||
- `escape_slots_content` - Whether to HTML-escape slot content (default: `True`)
|
||||
|
||||
All arguments are optional. If not provided, they default to empty values or sensible defaults.
|
||||
|
||||
|
|
|
@ -770,10 +770,10 @@ print(slot.nodelist) # <django.template.Nodelist: ['Hello!']>
|
|||
|
||||
Slots content are automatically escaped by default to prevent XSS attacks.
|
||||
|
||||
In other words, it's as if you would be using Django's [`mark_safe()`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.safestring.mark_safe) function on the slot content:
|
||||
In other words, it's as if you would be using Django's [`escape()`](https://docs.djangoproject.com/en/5.2/ref/templates/builtins/#std-templatefilter-escape) on the slot contents / result:
|
||||
|
||||
```python
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.html import escape
|
||||
|
||||
class Calendar(Component):
|
||||
template = """
|
||||
|
@ -784,24 +784,28 @@ class Calendar(Component):
|
|||
|
||||
Calendar.render(
|
||||
slots={
|
||||
"date": mark_safe("<b>Hello</b>"),
|
||||
"date": escape("<b>Hello</b>"),
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
To disable escaping, you can pass `escape_slots_content=False` to
|
||||
[`Component.render()`](../../../reference/api#django_components.Component.render)
|
||||
or [`Component.render_to_response()`](../../../reference/api#django_components.Component.render_to_response)
|
||||
methods.
|
||||
To disable escaping, you can wrap the slot string or slot result in Django's [`mark_safe()`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.safestring.mark_safe):
|
||||
|
||||
!!! warning
|
||||
```py
|
||||
Calendar.render(
|
||||
slots={
|
||||
# string
|
||||
"date": mark_safe("<b>Hello</b>"),
|
||||
|
||||
If you disable escaping, you should make sure that any content you pass to the slots is safe,
|
||||
especially if it comes from user input!
|
||||
# function
|
||||
"date": lambda ctx: mark_safe("<b>Hello</b>"),
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
!!! info
|
||||
|
||||
If you're planning on passing an HTML string, check Django's use of
|
||||
Read more about Django's
|
||||
[`format_html`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.html.format_html)
|
||||
and [`mark_safe`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.safestring.mark_safe).
|
||||
|
||||
|
|
|
@ -164,10 +164,10 @@ def my_view(request):
|
|||
|
||||
Slots content are automatically escaped by default to prevent XSS attacks.
|
||||
|
||||
In other words, it's as if you would be using Django's [`mark_safe()`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.safestring.mark_safe) function on the slot content:
|
||||
In other words, it's as if you would be using Django's [`escape()`](https://docs.djangoproject.com/en/5.2/ref/templates/builtins/#std-templatefilter-escape) on the slot contents / result:
|
||||
|
||||
```python
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.html import escape
|
||||
|
||||
class Calendar(Component):
|
||||
template = """
|
||||
|
@ -178,24 +178,28 @@ class Calendar(Component):
|
|||
|
||||
Calendar.render(
|
||||
slots={
|
||||
"date": mark_safe("<b>Hello</b>"),
|
||||
"date": escape("<b>Hello</b>"),
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
To disable escaping, you can pass `escape_slots_content=False` to
|
||||
[`Component.render()`](../../reference/api#django_components.Component.render)
|
||||
or [`Component.render_to_response()`](../../reference/api#django_components.Component.render_to_response)
|
||||
methods.
|
||||
To disable escaping, you can wrap the slot string or slot result in Django's [`mark_safe()`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.safestring.mark_safe):
|
||||
|
||||
!!! warning
|
||||
```py
|
||||
Calendar.render(
|
||||
slots={
|
||||
# string
|
||||
"date": mark_safe("<b>Hello</b>"),
|
||||
|
||||
If you disable escaping, you should make sure that any content you pass to the slots is safe,
|
||||
especially if it comes from user input!
|
||||
# function
|
||||
"date": lambda ctx: mark_safe("<b>Hello</b>"),
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
!!! info
|
||||
|
||||
If you're planning on passing an HTML string, check Django's use of
|
||||
Read more about Django's
|
||||
[`format_html`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.html.format_html)
|
||||
and [`mark_safe`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.safestring.mark_safe).
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ nav:
|
|||
- Compatibility: compatibility.md
|
||||
- Installation: installation.md
|
||||
- Security notes 🚨: security_notes.md
|
||||
- Migrating: migrating.md
|
||||
- Community: community.md
|
||||
- Contributing: contributing.md
|
||||
- Development: development.md
|
||||
|
|
25
docs/overview/migrating.md
Normal file
25
docs/overview/migrating.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
Django-components is still in active development.
|
||||
|
||||
Since django-components is in pre-1.0 development, the public API is not yet frozen.
|
||||
This means that there may be breaking changes between minor versions.
|
||||
We try to minimize the number of breaking changes, but sometimes it's unavoidable.
|
||||
|
||||
When upgrading, please read the [Release notes](../../release_notes).
|
||||
|
||||
## Migrating in pre-v1.0
|
||||
|
||||
If you're on older pre-v1.0 versions of django-components, we recommend doing step-wise
|
||||
upgrades in the following order:
|
||||
|
||||
- [v0.26](../../release_notes/#v026)
|
||||
- [v0.50](../../release_notes/#v050)
|
||||
- [v0.70](../../release_notes/#v070)
|
||||
- [v0.77](../../release_notes/#v077)
|
||||
- [v0.81](../../release_notes/#v081)
|
||||
- [v0.85](../../release_notes/#v085)
|
||||
- [v0.92](../../release_notes/#v092)
|
||||
- [v0.100](../../release_notes/#v0100)
|
||||
- [v0.110](../../release_notes/#v0110)
|
||||
- [v0.140](../../release_notes/#v01400)
|
||||
|
||||
These versions introduced breaking changes that are not backwards compatible.
|
|
@ -208,7 +208,7 @@ When you render a component, you can access everything about the component:
|
|||
|
||||
- Component input: [args, kwargs, slots and context](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#component-inputs)
|
||||
- Component's template, CSS and JS
|
||||
- Django's [context processors](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#request-object-and-context-processors)
|
||||
- Django's [context processors](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#request-and-context-processors)
|
||||
- Unique [render ID](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#component-id)
|
||||
|
||||
```python
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue