# Advanced Views
## Class properties
### template_name
By default, the component name is used to determine what template should be used. For example, `hello_world.HelloWorldView` would by default use `unicorn/hello-world.html`. However, you can specify a particular template by setting `template_name` in the component.
```python
# hello_world.py
from django_unicorn.components import UnicornView
class HelloWorldView(UnicornView):
template_name = "unicorn/hello-world.html"
```
## Instance properties
### component_args
The arguments passed into the component.
```html
{% unicorn 'hello-arg' 'World' %}
```
```python
# hello_arg.py
from django_unicorn.components import UnicornView
class HelloArgView(UnicornView):
def mount(self):
assert self.component_args[0] == "World"
```
### component_kwargs
The keyword arguments passed into the component.
```html
{% unicorn 'hello-kwarg' hello='World' %}
```
```python
# hello_kwarg.py
from django_unicorn.components import UnicornView
class HelloKwargView(UnicornView):
def mount(self):
assert self.component_kwargs["hello"] == "World"
```
### request
The current `request`.
```python
# hello_world.py
from django_unicorn.components import UnicornView
class HelloWorldView(UnicornView):
def mount(self):
print("Initial request that rendered the component", self.request)
def test(self):
print("AJAX request that re-renders the component", self.request)
```
## Custom methods
Defined component instance methods with no arguments are made available to the Django template context and can be called like a property.
```python
# states.py
from django_unicorn.components import UnicornView
class StateView(UnicornView):
def all_states(self):
return ["Alabama", "Alaska", "Arizona", ...]
```
```html
{% for state in all_states %}
{{ state }}
{% endfor %}
{% endverbatim %}
```
:::{tip}
If the method is intensive and will be called multiple times, it can be cached with Django's `cached_property` to prevent duplicate API requests or database queries. The method will only be executed once per component rendering.
```python
# states.py
from django.utils.functional import cached_property
from django_unicorn.components import UnicornView
class StateView(UnicornView):
@cached_property
def all_states(self):
return ["Alabama", "Alaska", "Arizona", ...]
```
:::
## Instance methods
### mount()
Gets called when the component gets initialized or [reset](actions.md#reset).
```python
# hello_world.py
from django_unicorn.components import UnicornView
class HelloWorldView(UnicornView):
name = "original"
def mount(self):
self.name = "mounted"
```
### hydrate()
Gets called when the component data gets set.
```python
# hello_world.py
from django_unicorn.components import UnicornView
class HelloWorldView(UnicornView):
name = "original"
def hydrate(self):
self.name = "hydrated"
```
### updating(name, value)
Gets called before each property that will get set.
### updated(name, value)
Gets called after each property gets set.
### updating\_{property_name}(value)
Gets called before the specified property gets set.
### updated\_{property_name}(value)
Gets called after the specified property gets set.
### calling(name, args)
Gets called before each method that gets called.
### called(name, args)
Gets called after each method gets called.
### complete()
Gets called after all methods have been called.
### rendered(html)
Gets called after the component has been rendered.
### parent_rendered(html)
Gets called after the component's parent has been rendered (if applicable).
## Meta
Classes that derive from `UnicornView` can include a `Meta` class that provides some advanced options for the component.
### exclude
By default, all public attributes of the component are included in the context of the Django template and available to JavaScript. One way to protect internal-only data is to prefix the atteibute name with `_` to indicate it should stay private.
```python
# hello_state.py
from django_unicorn.components import UnicornView
class HelloStateView(UnicornView):
_all_states = (
"Alabama",
"Alaska",
...
"Wisconsin",
"Wyoming",
)
```
Another way to prevent that data from being available to the component template is to add it to the `Meta` class's `exclude` tuple.
```python
# hello_state.py
from django_unicorn.components import UnicornView
class HelloStateView(UnicornView):
all_states = (
"Alabama",
"Alaska",
...
"Wisconsin",
"Wyoming",
)
class Meta:
exclude = ("all_states", )
```
### javascript_exclude
To allow an attribute to be included in the the context to be used by a Django template, but not exposed to JavaScript, add it to the `Meta` class's `javascript_exclude` tuple.
```html
{% for state in all_states %}
{{ state }}
{% endfor %}
```
```python
# hello_state.py
from django_unicorn.components import UnicornView
class HelloStateView(UnicornView):
all_states = (
"Alabama",
"Alaska",
...
"Wisconsin",
"Wyoming",
)
class Meta:
javascript_exclude = ("all_states", )
```
### safe
By default, `unicorn` HTML encodes updated field values to prevent XSS attacks. You need to explicitly opt-in to allow a field to be returned without being encoded by adding it to the `Meta` class's `safe` tuple.
```html
{{ something_safe }}
```
```python
# safe_example.py
from django_unicorn.components import UnicornView
class SafeExampleView(UnicornView):
something_safe = ""
class Meta:
safe = ("something_safe", )
```
````{note}
A context variable can be marked as `safe` in the template with the normal Django template filter, as well.
```html
{{ something_safe|safe }}
```
````
## JavaScript Integration
### Call JavaScript from View
To integrate with other JavaScript functions, view methods can call an arbitrary JavaScript function after it gets rendered.
```html
```
```python
# call_javascript.py
from django_unicorn.components import UnicornView
class CallJavascriptView(UnicornView):
name = ""
def mount(self):
self.call("hello", "world")
def hello(self):
self.call("hello", self.name)
```
### Trigger Model Update
Normally when a model element gets changed by a user it will trigger an event which `Unicorn` listens for (either `input` or `blur` depending on if it has a `lazy` modifier). However, when setting an element with JavaScript those events do not fire. `Unicorn.trigger()` provides a way to trigger that event from JavaScript manually.
The first argument to `trigger` is the component name. The second argument is the value for the element's `unicorn:key`.
```html
```