Django Integration Guide
This guide demonstrates how to integrate Moltres with Django, providing seamless DataFrame operations within Django applications.
Overview
Moltres provides comprehensive Django integration with the following features:
Middleware for Error Handling - Automatic conversion of Moltres exceptions to Django HTTP responses
Database Connection Helpers - Easy integration with Django’s database routing and transaction management
Management Commands - Command-line utilities for executing Moltres queries
Template Tags - Query data directly in Django templates with caching support
Installation
Install Moltres with Django support:
pip install moltres[django]
Or install separately:
pip install moltres django
Quick Start
1. Configure Django Settings
Add Moltres to your Django settings.py:
INSTALLED_APPS = [
# ... other apps
'moltres.integrations.django',
]
MIDDLEWARE = [
# ... other middleware
'moltres.integrations.django.MoltresExceptionMiddleware',
]
2. Use in Views
from django.http import JsonResponse
from django.views import View
from moltres.integrations.django import get_moltres_db
from moltres import col
class UserListView(View):
def get(self, request):
# Get Moltres database connection
db = get_moltres_db(using='default')
# Query data with Moltres
df = db.table("users").select().where(col("active") == True)
results = df.collect()
return JsonResponse({'users': results}, safe=False)
3. Use in Templates
{% load moltres_tags %}
{% moltres_query "users" as users %}
{% for user in users %}
<div>{{ user.name }} - {{ user.email }}</div>
{% endfor %}
Middleware for Error Handling
The MoltresExceptionMiddleware automatically converts Moltres exceptions to appropriate Django HTTP responses.
Configuration
Add to MIDDLEWARE in settings.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.middleware.common.CommonMiddleware',
'moltres.integrations.django.MoltresExceptionMiddleware', # Add this
# ... other middleware
]
Error Mapping
The middleware maps Moltres exceptions to HTTP status codes:
DatabaseConnectionError→ 503 Service UnavailableConnectionPoolError→ 503 Service UnavailableQueryTimeoutError→ 504 Gateway TimeoutExecutionError(not found) → 404 Not FoundExecutionError(permission) → 403 ForbiddenExecutionError(syntax error) → 400 Bad RequestExecutionError(generic) → 500 Internal Server ErrorCompilationError→ 400 Bad RequestValidationError→ 400 Bad RequestColumnNotFoundError→ 400 Bad RequestTransactionError→ 500 Internal Server ErrorMoltresError→ 500 Internal Server Error
Example
from django.http import JsonResponse
from moltres.integrations.django import get_moltres_db
def my_view(request):
db = get_moltres_db(using='default')
# If this raises a Moltres exception, the middleware will
# automatically convert it to an appropriate HTTP response
df = db.table("nonexistent_table").select()
results = df.collect() # Raises ExecutionError → 404 response
return JsonResponse({'data': results})
Database Connection Helpers
Basic Usage
The get_moltres_db() function creates a Moltres Database instance from Django’s database configuration:
from moltres.integrations.django import get_moltres_db
from moltres import col
def my_view(request):
# Get database connection (uses 'default' database)
db = get_moltres_db(using='default')
# Use Moltres operations
df = db.table("users").select().where(col("age") > 25)
results = df.collect()
return JsonResponse({'users': results}, safe=False)
Database Routing
Moltres supports Django’s database routing:
from moltres.integrations.django import get_moltres_db
def my_view(request):
# Route to read replica for GET requests
db_alias = 'read_replica' if request.method == 'GET' else 'default'
db = get_moltres_db(using=db_alias)
df = db.table("users").select()
results = df.collect()
return JsonResponse({'users': results}, safe=False)
Supported Databases
The integration supports the following Django database backends:
SQLite -
django.db.backends.sqlite3PostgreSQL -
django.db.backends.postgresqlordjango.contrib.gis.db.backends.postgisMySQL -
django.db.backends.mysql
For other databases, use connect() directly with a DSN string.
Transaction Management
Moltres integrates with Django’s transaction management:
from django.db import transaction
from moltres.integrations.django import get_moltres_db
from moltres.io.records import Records
@transaction.atomic
def create_user_with_orders(request):
db = get_moltres_db(using='default')
# All operations are part of the same transaction
Records(
_data=[{"name": "Alice", "email": "alice@example.com"}],
_database=db,
).insert_into("users")
Records(
_data=[{"user_id": 1, "product": "Widget", "amount": 100.0}],
_database=db,
).insert_into("orders")
# If any operation fails, all are rolled back
Management Commands
Basic Usage
Execute Moltres queries from the command line:
python manage.py moltres_query "db.table('users').select()"
Options
# Use different database
python manage.py moltres_query "db.table('users').select()" --database=read_replica
# Output as JSON
python manage.py moltres_query "db.table('users').select()" --format=json
# Output as CSV
python manage.py moltres_query "db.table('users').select()" --format=csv
# Interactive mode
python manage.py moltres_query --interactive
# Read query from file
python manage.py moltres_query --file=query.txt
Interactive Mode
Interactive mode allows you to explore data interactively:
$ python manage.py moltres_query --interactive
Moltres Interactive Query Mode
Type 'exit' or 'quit' to exit
Type 'help' for help
moltres> db.table("users").select()
id | name | email
---|-------|----------
1 | Alice | alice@example.com
2 | Bob | bob@example.com
moltres> db.table("users").select().where(col("age") > 25)
id | name | email
---|------|----------
1 | Alice| alice@example.com
moltres> exit
Example Queries
# Simple select
python manage.py moltres_query "db.table('users').select()"
# With filtering
python manage.py moltres_query "db.table('users').select().where(col('active') == True)"
# With aggregation
python manage.py moltres_query "db.table('orders').select().group_by('status').agg(F.count(col('id')).alias('count'))"
# Complex query
python manage.py moltres_query "db.table('users').select().join(db.table('orders').select(), on=[col('users.id') == col('orders.user_id')])"
Complete Example
Here’s a complete example of a Django app using Moltres:
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'moltres.integrations.django', # Add Moltres
'myapp',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'moltres.integrations.django.MoltresExceptionMiddleware', # Add Moltres middleware
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
views.py
from django.http import JsonResponse
from django.views import View
from moltres.integrations.django import get_moltres_db
from moltres import col
from moltres.expressions import functions as F
from moltres.io.records import Records
from moltres.table.schema import column
class UserListView(View):
def get(self, request):
db = get_moltres_db(using='default')
# Query with filtering
df = db.table("users").select()
# Apply filters from query parameters
min_age = request.GET.get("min_age")
if min_age:
df = df.where(col("age") >= int(min_age))
search = request.GET.get("search")
if search:
df = df.where(
(col("name").like(f"%{search}%")) |
(col("email").like(f"%{search}%"))
)
results = df.collect()
return JsonResponse({'users': results}, safe=False)
class UserStatsView(View):
def get(self, request):
db = get_moltres_db(using='default')
df = db.table("users").select()
# Calculate statistics
stats_df = df.select(
F.count(col("id")).alias("total_users"),
F.avg(col("age")).alias("avg_age"),
F.min(col("age")).alias("min_age"),
F.max(col("age")).alias("max_age"),
)
stats = stats_df.collect()[0]
return JsonResponse({
'total_users': stats['total_users'],
'average_age': round(stats['avg_age'], 2),
'min_age': stats['min_age'],
'max_age': stats['max_age'],
})
class UserCreateView(View):
def post(self, request):
import json
db = get_moltres_db(using='default')
data = json.loads(request.body)
# Ensure table exists (use migrations in production)
try:
db.create_table(
"users",
[
column("id", "INTEGER", primary_key=True),
column("name", "TEXT"),
column("email", "TEXT"),
column("age", "INTEGER"),
],
).collect()
except Exception:
pass # Table might already exist
# Insert user
Records(
_data=[{
"name": data.get("name"),
"email": data.get("email"),
"age": data.get("age"),
}],
_database=db,
).insert_into("users")
return JsonResponse({'status': 'created'}, status=201)
template.html
{% load moltres_tags %}
<h1>Users</h1>
{% moltres_query "users" cache_timeout=3600 as users %}
<ul>
{% for user in users %}
<li>{{ user.name }} ({{ user.email }}) - Age: {{ user.age }}</li>
{% endfor %}
</ul>
<p>Total users: {{ users|moltres_format:"count" }}</p>
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('api/users/', views.UserListView.as_view(), name='user-list'),
path('api/users/stats/', views.UserStatsView.as_view(), name='user-stats'),
path('api/users/create/', views.UserCreateView.as_view(), name='user-create'),
]
Best Practices
1. Use Database Routing
Route read queries to read replicas:
def my_view(request):
db_alias = 'read_replica' if request.method == 'GET' else 'default'
db = get_moltres_db(using=db_alias)
# ... use db
2. Cache Template Queries
Cache expensive queries in templates:
{% moltres_query "expensive_query" cache_timeout=3600 as results %}
3. Use Transactions
Wrap related operations in transactions:
from django.db import transaction
@transaction.atomic
def create_user_with_profile(request):
db = get_moltres_db(using='default')
# ... multiple operations
4. Error Handling
The middleware handles errors automatically, but you can also handle them manually:
from moltres.utils.exceptions import ExecutionError
def my_view(request):
try:
db = get_moltres_db(using='default')
df = db.table("users").select()
results = df.collect()
except ExecutionError as e:
# Handle specific error
return JsonResponse({'error': str(e)}, status=404)
return JsonResponse({'users': results}, safe=False)
5. Use Management Commands for Data Exploration
Use the management command for interactive data exploration:
python manage.py moltres_query --interactive
Troubleshooting
ImportError: Django is required
If you see this error, install Django:
pip install django
Or install Moltres with Django support:
pip install moltres[django]
Database Connection Errors
Ensure your Django database settings are correct:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # or postgresql, mysql
'NAME': 'your_database_name',
# ... other settings
}
}
Template Tag Not Found
Ensure you’ve loaded the template tags:
{% load moltres_tags %}
Management Command Not Found
Ensure Moltres Django integration is in INSTALLED_APPS:
INSTALLED_APPS = [
# ... other apps
'moltres.integrations.django',
]
See Also
FastAPI Integration Guide - Similar patterns for FastAPI
SQLAlchemy Integration Guide - Using Moltres with SQLAlchemy
Examples - Complete Django integration examples