# Templates
Templates are normal Django HTML templates, so anything you could normally do in a Django template will still work, including template tags, filters, loops, if statements, etc.
```{warning}
`Unicorn` requires there to be one root element that contains the component HTML. Valid HTML and a wrapper element is required for the DOM diffing algorithm to work correctly, so `Unicorn` will try to log a warning message if they seem invalid.
For example, this is an **invalid** template:
:::{code} html
:force: true
Name: {{ name }}
:::
This template is **valid**:
:::{code} html
:force: true
Name: {{ name }}
:::
```
## Unicorn attributes
`Unicorn` element attributes usually start with `unicorn:`, however the shortcut `u:` is also supported. So, for example, `unicorn:model` could also be written as `u:model`.
## Accessing nested fields
Fields in a `dictionary` or Django model can be accessed similarly to the Django template language with "dot notation".
```python
# hello_world.py
from django_unicorn.components import UnicornView
from book.models import Book
class HelloWorldView(UnicornView):
book: Book
book_ratings: dict[str[dict[str, str]]]
def mount(self):
book = Book.objects.get(title='American Gods')
book_ratings = {'excellent': {'title': 'American Gods'}}
```
```html
```
```{note}
[Django models](django-models.md) has many more details about using Django models in `Unicorn`.
```
## Model modifiers
### Lazy
To prevent updates from happening on _every_ input, you can append a `lazy` modifier to the end of `unicorn:model`. That will only update the component when a `blur` event happens.
:::{code} html
:force: true
Hello {{ name|title }}
:::
### Debounce
The `debounce` modifier configures how long to wait to fire an event. The time is always specified in milliseconds, for example: `unicorn:model.debounce-1000` would wait for 1000 milliseconds (1 second) before firing the message.
:::{code} html
:force: true
Hello {{ name|title }}
:::
### Defer
The `defer` modifier will store and save model changes until the next action gets triggered. This is useful to prevent additional network requests until an action is triggered.
:::{code} html
:force: true
{% for task in tasks %}
{{ task }}
{% endfor %}
:::
### Chaining modifiers
`Lazy` and `debounce` modifiers can even be chained together.
:::{code} html
:force: true
Hello {{ name|title }}
:::
## Key
### Smooth updates
Setting a unique `id` on elements with `unicorn:model` will prevent changes to an input from being choppy when there are lots of updates in quick succession.
```html
```
```html
!-- smooth-updates.html -->
```
The `unicorn:key` attribute can be used when multiple elements have the same `id`.
```html
```
```html
```
### DOM merging
To merge changes in the DOM, `Unicorn` uses, in order, `unicorn:id`, `unicorn:key`, or the element's `id` to intelligently update DOM elements.
## Lifecycle events
`Unicorn` provides events that fire when different parts of the lifecycle occur.
### updated
The `updated` event is fired after the AJAX call finishes and the component is merged with the newly rendered component template. The callback gets called with one argument, `component`.
```html
```
## Ignore elements
Some JavaScript libraries will change the DOM (such as `Select2`) after the page renders. That can cause issues for `Unicorn` when trying to merge that DOM with what `Unicorn` _thinks_ the DOM should be. `unicorn:ignore` can be used to prevent `Unicorn` from morphing that element or its children.
```{note}
When the component is initially rendered, normal Django template functionality can be used.
```
```html