mirror of
https://github.com/django-components/django-components.git
synced 2025-08-04 14:28:18 +00:00
docs: update section on working with request object (#1126)
* docs: update section on working with request object * refactor: fix linting
This commit is contained in:
parent
06cad2ec64
commit
fc026cbd99
3 changed files with 83 additions and 45 deletions
|
@ -1,25 +1,22 @@
|
|||
The most common use of django-components is to render HTML for a given request. As such,
|
||||
The most common use of django-components is to render HTML when the server receives a request. As such,
|
||||
there are a few features that are dependent on the request object.
|
||||
|
||||
## Passing and accessing HttpRequest
|
||||
## Passing the HttpRequest object
|
||||
|
||||
In regular Django templates, the request object is available only within the `RequestContext`.
|
||||
In regular Django templates, the request object is available only within the [`RequestContext`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.RequestContext).
|
||||
|
||||
In Components, you can either use `RequestContext`, or pass the `request` object
|
||||
In Components, you can either use [`RequestContext`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.RequestContext), or pass the `request` object
|
||||
explicitly to [`Component.render()`](../../../reference/api#django_components.Component.render) and
|
||||
[`Component.render_to_response()`](../../../reference/api#django_components.Component.render_to_response).
|
||||
|
||||
When a component is nested in another, the child component uses parent's `request` object.
|
||||
So the request object is available to components either when:
|
||||
|
||||
You can access the request object under [`Component.request`](../../../reference/api#django_components.Component.request):
|
||||
- The component is rendered with [`RequestContext`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.RequestContext) (Regular Django behavior)
|
||||
- The component is rendered with a regular [`Context`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.Context) (or none), but you set the `request` kwarg
|
||||
of [`Component.render()`](../../../reference/api#django_components.Component.render).
|
||||
- The component is nested and the parent has access to the request object.
|
||||
|
||||
```python
|
||||
class MyComponent(Component):
|
||||
def get_context_data(self):
|
||||
return {
|
||||
'user_id': self.request.GET['user_id'],
|
||||
}
|
||||
|
||||
# ✅ With request
|
||||
MyComponent.render(request=request)
|
||||
MyComponent.render(context=RequestContext(request, {}))
|
||||
|
@ -29,31 +26,7 @@ MyComponent.render()
|
|||
MyComponent.render(context=Context({}))
|
||||
```
|
||||
|
||||
## Context Processors
|
||||
|
||||
Components support Django's [context processors](https://docs.djangoproject.com/en/5.1/ref/templates/api/#using-requestcontext).
|
||||
|
||||
In regular Django templates, the context processors are applied only when the template is rendered with `RequestContext`.
|
||||
|
||||
Components allow you to pass the `request` object explicitly. Thus, the context processors are applied to components either when:
|
||||
|
||||
- The component is rendered with `RequestContext` (Regular Django behavior)
|
||||
- The component is rendered with a regular `Context` (or none), but you set the `request` kwarg
|
||||
of [`Component.render()`](../../../reference/api#django_components.Component.render).
|
||||
- The component is nested in another component that matches one of the two conditions above.
|
||||
|
||||
```python
|
||||
# ❌ No context processors
|
||||
rendered = MyComponent.render()
|
||||
rendered = MyComponent.render(Context({}))
|
||||
|
||||
# ✅ With context processors
|
||||
rendered = MyComponent.render(request=request)
|
||||
rendered = MyComponent.render(Context({}), request=request)
|
||||
rendered = MyComponent.render(RequestContext(request, {}))
|
||||
```
|
||||
|
||||
When a component is rendered within a template with [`{% component %}`](../../../reference/template_tags#component) tag, context processors are available depending on whether the template is rendered with `RequestContext` or not.
|
||||
When a component is rendered within a template with [`{% component %}`](../../../reference/template_tags#component) tag, the request object is available depending on whether the template is rendered with [`RequestContext`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.RequestContext) or not.
|
||||
|
||||
```python
|
||||
template = Template("""
|
||||
|
@ -62,13 +35,33 @@ template = Template("""
|
|||
</div>
|
||||
""")
|
||||
|
||||
# ❌ No context processors
|
||||
# ❌ No request
|
||||
rendered = template.render(Context({}))
|
||||
|
||||
# ✅ With context processors
|
||||
# ✅ With request
|
||||
rendered = template.render(RequestContext(request, {}))
|
||||
```
|
||||
|
||||
## Accessing the HttpRequest object
|
||||
|
||||
When the component has access to the `request` object, the request object will be available in [`Component.request`](../../../reference/api/#django_components.Component.request).
|
||||
|
||||
```python
|
||||
class MyComponent(Component):
|
||||
def get_context_data(self):
|
||||
return {
|
||||
'user_id': self.request.GET['user_id'],
|
||||
}
|
||||
```
|
||||
|
||||
## Context Processors
|
||||
|
||||
Components support Django's [context processors](https://docs.djangoproject.com/en/5.1/ref/templates/api/#using-requestcontext).
|
||||
|
||||
In regular Django templates, the context processors are applied only when the template is rendered with [`RequestContext`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.RequestContext).
|
||||
|
||||
In Components, the context processors are applied when the component has access to the `request` object.
|
||||
|
||||
### Accessing context processors data
|
||||
|
||||
The data from context processors is automatically available within the component's template.
|
||||
|
@ -94,3 +87,11 @@ class MyComponent(Component):
|
|||
'csrf_token': csrf_token,
|
||||
}
|
||||
```
|
||||
|
||||
This is a dictionary with the context processors data.
|
||||
|
||||
If the request object is not available, then [`self.context_processors_data`](../../../reference/api/#django_components.Component.context_processors_data) will be an empty dictionary.
|
||||
|
||||
!!! warning
|
||||
|
||||
The [`self.context_processors_data`](../../../reference/api/#django_components.Component.context_processors_data) object is generated dynamically, so changes to it are not persisted.
|
||||
|
|
|
@ -68,6 +68,7 @@ and [`self.input.kwargs`](../../../reference/api/#django_components.ComponentInp
|
|||
to access the positional and keyword arguments passed to [`Component.render()`](../../../reference/api/#django_components.Component.render).
|
||||
|
||||
```python
|
||||
class Table(Component):
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
# Access component's inputs, slots and context
|
||||
assert self.input.args == [123, "str"]
|
||||
|
@ -100,6 +101,8 @@ This is a dictionary with the context processors data.
|
|||
|
||||
If the request object is not available, then [`self.context_processors_data`](../../../reference/api/#django_components.Component.context_processors_data) will be an empty dictionary.
|
||||
|
||||
Read more about the request object and context processors in the [HTTP Request](./http_request.md) section.
|
||||
|
||||
```python
|
||||
from django.http import HttpRequest
|
||||
|
||||
|
@ -115,7 +118,3 @@ rendered = Table.render(
|
|||
request=HttpRequest(),
|
||||
)
|
||||
```
|
||||
|
||||
!!! warning
|
||||
|
||||
The [`self.context_processors_data`](../../../reference/api/#django_components.Component.context_processors_data) object is generated dynamically, so changes to it are not persisted.
|
||||
|
|
|
@ -751,10 +751,48 @@ class Component(
|
|||
@property
|
||||
def input(self) -> ComponentInput[ArgsType, KwargsType, SlotsType]:
|
||||
"""
|
||||
Input holds the data (like arg, kwargs, slots) that were passed to
|
||||
the current execution of the `render` method.
|
||||
Input holds the data that were passed to the current component at render time.
|
||||
|
||||
Raises `RuntimeError` if accessed outside of rendering execution.
|
||||
|
||||
This includes:
|
||||
|
||||
- [`args`](../api/#django_components.ComponentInput.args) - List of positional arguments
|
||||
- [`kwargs`](../api/#django_components.ComponentInput.kwargs) - Dictionary of keyword arguments
|
||||
- [`slots`](../api/#django_components.ComponentInput.slots) - Dictionary of slots. Values are normalized to
|
||||
[`Slot`](../api/#django_components.Slot) instances
|
||||
- [`context`](../api/#django_components.ComponentInput.context) -
|
||||
[`Context`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.Context)
|
||||
object that should be used to render the component
|
||||
- And other kwargs passed to [`Component.render()`](../api/#django_components.Component.render)
|
||||
like `type` and `render_dependencies`
|
||||
|
||||
Read more on [Component inputs](../../concepts/fundamentals/render_api/#component-inputs).
|
||||
|
||||
**Example:**
|
||||
|
||||
Use can use [`self.input.args`](../api/#django_components.ComponentInput.args)
|
||||
and [`self.input.kwargs`](../api/#django_components.ComponentInput.kwargs)
|
||||
to access the positional and keyword arguments passed to
|
||||
[`Component.render()`](../api/#django_components.Component.render).
|
||||
|
||||
```python
|
||||
class Table(Component):
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
# Access component's inputs, slots and context
|
||||
assert self.input.args == [123, "str"]
|
||||
assert self.input.kwargs == {"variable": "test", "another": 1}
|
||||
footer_slot = self.input.slots["footer"]
|
||||
some_var = self.input.context["some_var"]
|
||||
|
||||
return {}
|
||||
|
||||
rendered = TestComponent.render(
|
||||
kwargs={"variable": "test", "another": 1},
|
||||
args=(123, "str"),
|
||||
slots={"footer": "MY_SLOT"},
|
||||
)
|
||||
```
|
||||
"""
|
||||
if not len(self._metadata_stack):
|
||||
raise RuntimeError(f"{self.name}: Tried to access Component input while outside of rendering execution")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue