# Route overrides

{% hint style="success" %}
This is the official documentation of the `forestadmin-agent-django` and `forestadmin-agent-flask` Python agents.
{% endhint %}

[Route overrides](https://docs.forestadmin.com/documentation/reference-guide/routes/override-a-route) allowed customizing the behavior of the routes exposed by the agent.

This very low-level feature was used to implement many use cases:

* Attach handlers to events in the UI
* Customize filtering, search and sort behaviors
* Other advanced use cases.

Because our new agent API is higher-level, the protocol used to communicate between the agent and the application can no longer be manipulated.

## Code cheatsheet

| What was the route override used for?   | How to migrate it?                                                                                                                                                                    |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Add custom permissions                  | Use [.add\_hook](/developer-guide-agents-python/agent-customization/hooks.md) and throw `forbidden errors`                                                                            |
| Add validation to fields                | Use [.add\_field\_validation](/developer-guide-agents-python/agent-customization/fields/validation.md) instead                                                                        |
| Add validation to whole records         | Use [.add\_hook](/developer-guide-agents-python/agent-customization/hooks.md) and throw `validation errors`                                                                           |
| Run code on UI events                   | Use [.add\_hook](/developer-guide-agents-python/agent-customization/hooks.md) to perform custom logic                                                                                 |
| Change the search behavior              | Use [.replace\_search](/developer-guide-agents-python/agent-customization/search.md) to implement your custom search logic                                                            |
| Change the filtering behavior of fields | Use [.replace\_field\_operator](/developer-guide-agents-python/agent-customization/fields/filter.md)                                                                                  |
| Change the sort behavior of fields      | Use [.replace\_field\_sorting](/developer-guide-agents-python/agent-customization/fields/sort.md)                                                                                     |
| Other use case                          | If you are stuck or think that this guide can be improved, please [expose your use case in the community forums](https://community.forestadmin.com/) and we will be happy to help you |

## Examples

### Add custom permissions

{% hint style="warning" %}
Custom permissions would better be implemented by using the [Roles](https://docs.forestadmin.com/user-guide/project-settings/teams-and-users/manage-roles) feature from the UI.
{% endhint %}

{% tabs %}
{% tab title="Before" %}

* Define a new route into your `urls.py` file:
* Add a new method in your controller.

```python
from django.http import  HttpResponse
from django.views import generic

from app.models import Book

class BooksView(generic.ListView):
    def delete(self, request, pk, *args, **kwargs):
        Book.objects.filter(id=pk).delete()

        return HttpResponse(status=204)
```

{% endtab %}

{% tab title="After" %}

```python
from forestadmin.datasource_toolkit.decorators.hook.context.delete import (
    HookBeforeDeleteContext
)

def before_delete_hook(context: HookBeforeDeleteContext):
    is_allowed = True  # Your logic here

    if is_allowed is False:
        context.throw_forbidden_error(
            "This collection is protected, you cannot remove from it."
        )

agent.customize_collection('Book').add_hook('Before', 'Delete', before_delete_hook)
```

{% endtab %}
{% endtabs %}

### Add validation to fields

{% tabs %}
{% tab title="Before" %}

* Define a new route into your `urls.py` file.
* Add a new method to your controller.

```python
import re

from django.http import  HttpResponse
from django_forest.resources.views.detail import DetailView
from django_forest.resources.views.list import ListView

from app.models import Book

class CompanyView(ListView):
    def post(self, request, pk, *args, **kwargs):
        patch = self.get_body(request.body)["data"]["attributes"]

        if "name" in patch and re.search(r'^Forest', patch["name"]):
            return self.error_response(
                "All company names should begin with 'Forest'."
            )

        return super().post(request, pk, *args, **kwargs)

class CompanyDetailView(DetailView):
    def put(self, request, pk):
        patch = self.get_body(request.body)["data"]["attributes"]

        if "name" in patch and re.search(r'^Forest', patch["name"]):
            return self.error_response(
                "All company names should begin with 'Forest'."
            )

        return super().put(request, pk)
```

{% endtab %}

{% tab title="After" %}

```python
agent.customize_collection('companies').add_field_validation(
    'name', 'match', r'^Forest'
)
```

{% endtab %}
{% endtabs %}

### Run code on UI events

{% tabs %}
{% tab title="Before" %}

* Define a new route into your `urls.py` file:
* Add a new method to your controller.

```python
from django_forest.resources.views.list import ListView

class CustomerView(ListView):
    def post(self, request, pk, *args, **kwargs):
        try:
            superagent.post('https://my-company/create-card').set(
                'X-API-Key', '**********'
            ).end()
        finally:
            return super().post(request, pk, *args, **kwargs)

```

{% endtab %}

{% tab title="After" %}

```python
from forestadmin.datasource_toolkit.decorators.hook.context.create import (
    HookBeforeCreateContext
)

def before_create_hook(context: HookBeforeCreateContext):
    superagent.post('https://my-company/create-card').set(
        'X-API-Key', '***********'
    ).end()

agent.customize_collection('customers').add_hook(
    'Before', 'Create', before_create_hook
)
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestadmin.com/developer-guide-agents-python/getting-started/migrating/code-transformations/route-overrides.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
