Chat With Your Data: Integrating PandasAI in Django Admin
Django admin is where a lot of internal business tooling lives. It's fast to build, it's secure out of the box, and it handles the basics well. But the moment a non-technical stakeholder wants to ask a question like "how many users signed up last week by country, broken down by plan type?" — they're either blocked until an engineer writes a custom view, or they're exporting to CSV and wrestling with spreadsheets.
PandasAI is an open-source library that adds a natural language interface to Pandas DataFrames. Combined with Django admin, it becomes a quick way to give non-technical users self-service access to business data without building a full BI tool.
What PandasAI does
PandasAI wraps a Pandas DataFrame with an LLM-powered interface. You can ask questions in plain English and get back charts, tables, or calculated values:
from pandasai import SmartDataframe
import pandas as pd
df = SmartDataframe(pd.DataFrame(data))
df.chat("What were the top 5 products by revenue last month?") Under the hood, PandasAI converts the natural language query to Pandas code via an LLM, executes it against the DataFrame, and returns the result. It supports OpenAI, Anthropic, Ollama, and other backends.
Integrating with Django admin
The integration has three parts: a view to load the data and handle the query, a form for user input, and a template to display the result.
First, create a custom admin view:
# admin.py
from django.contrib import admin
from django.shortcuts import render
from django.http import HttpResponse
from pandasai import SmartDataframe
from pandasai.llm import OpenAI
import pandas as pd
from .models import Order
class OrderAdmin(admin.ModelAdmin):
def get_urls(self):
from django.urls import path
urls = super().get_urls()
custom_urls = [
path('chat/', self.admin_site.admin_view(self.chat_view), name='order-chat'),
]
return custom_urls + urls
def chat_view(self, request):
result = None
if request.method == 'POST':
question = request.POST.get('question')
qs = Order.objects.values('created_at', 'total', 'country', 'plan')
df = pd.DataFrame(list(qs))
llm = OpenAI(api_token=settings.OPENAI_API_KEY)
smart_df = SmartDataframe(df, config={"llm": llm})
result = smart_df.chat(question)
return render(request, 'admin/order_chat.html', {'result': result})
admin.site.register(Order, OrderAdmin) Security considerations
This pattern has a real security surface to manage:
- Scope the DataFrame — only include the columns users should see. Don't pass the full queryset; select only the fields relevant to the queries you want to enable. Never include PII unless explicitly needed.
- Restrict to admin users — the
admin_viewwrapper requires authentication. Add permission checks for sensitive data views. - LLM prompt injection — a user could construct a question designed to manipulate the LLM into generating code that accesses more than the DataFrame. PandasAI runs in a sandboxed execution context, but review the library's sandbox configuration before deploying.
- API cost controls — every query hits the LLM API. Set rate limits per user or add a query approval flow for high-cost queries (e.g., queries that load large DataFrames).
When this is worth doing
This pattern is best suited to internal tools where:
- The primary users are trusted (internal team, not external customers)
- The data fits in memory as a DataFrame (up to a few million rows, depending on your server)
- The alternative is building and maintaining custom admin views for every ad-hoc query request
For larger datasets, consider sampling or aggregating before loading into the DataFrame, or look at tools like Metabase or Redash which are purpose-built for this use case. PandasAI in Django admin is the right tool for teams that already live in Django admin and want to avoid standing up a separate BI stack.
What it replaces
Before this pattern, every stakeholder question that couldn't be answered by the built-in list view became a developer task: write a custom changelist filter, add a calculated field, or export to CSV. This adds up to a non-trivial fraction of engineering time at small companies.
A natural language interface doesn't replace all of that — complex dashboards still need dedicated tooling. But for the long tail of "can you just tell me..." questions, it's a fast way to unblock stakeholders without writing custom code for every question.