This is the official documentation of the forestadmin-agent-django and forestadmin-agent-flask Python agents.
Route overrides ↗ 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
Add validation to fields
Add validation to whole records
Run code on UI events
Change the search behavior
Change the filtering behavior of fields
Change the sort behavior of fields
Other use case
Examples
Add custom permissions
Custom permissions would better be implemented by using the Roles ↗ feature from the UI.
Define a new route into your urls.py file:
Add a new method in your controller.
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)
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)
Add validation to fields
Define a new route into your urls.py file.
Add a new method to your controller.
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)