# Child components
`Unicorn` supports nesting components so that one component is a child of another. Since HTML is a tree structure, a component can have multiple children, but each child only has one parent.
We will slowly build a nested component example with three components: `table`, `filter`, and `row`. The table is the parent and contains the other two components. The filter will update the parent table component, and the row will contain functionality to edit a row.
## Parent component
```html
{% load unicorn %}
{% unicorn 'filter' %}
Author
Title
{% for book in books %}
{{ book.author }}
{{ book.title }}
{% endfor %}
```
```python
# table.py
from book.models import Book
from django_unicorn.components import UnicornView
class TableView(UnicornView):
books = Book.objects.none()
def mount(self):
self.load_table()
def load_table(self):
self.books = Book.objects.all()[0:10]
```
## Child component
The child component, `filter`, will have access to its parent through the view's `self.parent`. The `FilterView` is using the [updated](https://www.django-unicorn.com/docs/advanced/#updated-property-name-value) method to filter the `books` queryset on the table component when the filter's `search` model is changed.
```html
```
```python
from django_unicorn.components import UnicornView
class FilterView(UnicornView):
search = ""
def updated_search(self, query):
self.parent.load_table()
if query:
self.parent.books = list(
filter(lambda f: query.lower() in f.title.lower(), self.parent.books)
)
# Forces the parent to re-render instead of just the current component
self.parent.force_render = True
```
## Multiple children
If we want to encapsulate the editing and saving of a row of data, we can add in a row component as well.
```{note}
The [discard](actions.md#discard) action modifier is used on the cancel button to provide an easy way to prevent any edits from being saved.
```
:::{code} html
:force: true
:::
```python
# row.py
from django_unicorn.components import UnicornView
class RowView(UnicornView):
book = None
is_editing = False
def edit(self):
self.is_editing = True
def cancel(self):
self.is_editing = False
def save(self):
self.book.save()
self.is_editing = False
```
The changes for the table component where the row child component is added in. Views will always have a `children` attribute -- here it is used to set `is_editing` to `false` on all rows when the table gets reloaded.
```html
{% load unicorn %}
{% unicorn 'filter' %}
Author
Title
{% for book in books %}
{% unicorn 'row' book=book key=book.id %}
{% endfor %}
```
```python
# table.py
from book.models import Book
from django_unicorn.components import UnicornView
class TableView(UnicornView):
books = Book.objects.none()
def mount(self):
self.load_table()
def load_table(self):
self.books = Book.objects.all()
for child in self.children:
if hasattr(child, "is_editing"):
child.is_editing = False
```
````{warning}
`Unicorn` requires components to have a unique identifier. Normally that is handled automatically, however multiple child components with the same component name require some help.
For child components, `unicorn:id` is automatically created from the parent's `unicorn:id` and the child's component name. If a child component is created multiple times in the same parent, one of the following can be used to create unique identifiers:
- pass in a `key` keyword argument to the child component
```html
{% unicorn 'row' book=book key=book.id %}
```
- pass in an `id` keyword argument to the child component
```html
{% unicorn 'row' book=book id=book.id %}
```
- the view has an attribute named `model` which has either a `pk` or `id` attribute
```html
{% unicorn 'row' model=book %}
```
````