Supabase Django integration
Supabase Integration with Django
Here's a guide to integrating Supabase with a Django application. We will use the requests
library to make API calls to Supabase, as there is no official Django-specific Supabase ORM.
Set Up Your Supabase Project
First, you need a Supabase project.
- Go to the Supabase Dashboard.
- Create a new project.
- Navigate to API Settings to find your
Project URL
andanon public key
. You will use these in your Django settings. - Create a test table, for example,
products
, with a few columns likeid
(primary key),name
, andprice
.
Set Up Your Django Project
Next, set up a new Django project and a virtual environment.
# Create a virtual environment
python3 -m venv venv
source venv/bin/activate
# Install Django and the requests library
pip install Django requests
Create a new Django project and app:
django-admin startproject myproject
cd myproject
python manage.py startapp products
In myproject/settings.py
, add your new products
app and your Supabase credentials. It's crucial to use environment variables for sensitive data in a production environment.
# myproject/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'products', # Your new app
]
# Supabase Credentials
SUPABASE_URL = os.environ.get("SUPABASE_URL", "https://your-project-ref.supabase.co")
SUPABASE_KEY = os.environ.get("SUPABASE_KEY", "eyJhbGciOiJIUzI1NiIsIn...")
Create a Supabase API Wrapper
To keep your code clean, create a simple wrapper for Supabase API calls. In your products
app, create a file named supabase_client.py
.
# products/supabase_client.py
import os
import requests
SUPABASE_URL = os.environ.get("SUPABASE_URL")
SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
class SupabaseClient:
def __init__(self, table_name):
self.url = f"{SUPABASE_URL}/rest/v1/{table_name}"
self.headers = {
"apikey": SUPABASE_KEY,
"Authorization": f"Bearer {SUPABASE_KEY}",
"Content-Type": "application/json"
}
def get_all(self):
response = requests.get(self.url, headers=self.headers)
response.raise_for_status()
return response.json()
def get_by_id(self, item_id):
response = requests.get(f"{self.url}?id=eq.{item_id}", headers=self.headers)
response.raise_for_status()
return response.json()
def create(self, data):
response = requests.post(self.url, json=data, headers=self.headers)
response.raise_for_status()
return response.json()
def update(self, item_id, data):
response = requests.patch(f"{self.url}?id=eq.{item_id}", json=data, headers=self.headers)
response.raise_for_status()
return response.json()
def delete(self, item_id):
response = requests.delete(f"{self.url}?id=eq.{item_id}", headers=self.headers)
response.raise_for_status()
return response.json()
Create Views and URLs
Now, create your views in products/views.py
to use the client wrapper.
# products/views.py
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from .supabase_client import SupabaseClient
import json
product_client = SupabaseClient("products")
@require_http_methods(["GET", "POST"])
def product_list_create(request):
if request.method == "GET":
products = product_client.get_all()
return JsonResponse(products, safe=False)
elif request.method == "POST":
data = json.loads(request.body)
new_product = product_client.create(data)
return JsonResponse(new_product, status=201, safe=False)
@require_http_methods(["GET", "PUT", "DELETE"])
def product_detail(request, product_id):
if request.method == "GET":
product = product_client.get_by_id(product_id)
if product:
return JsonResponse(product[0], safe=False)
return JsonResponse({"error": "Product not found"}, status=404)
elif request.method == "PUT":
data = json.loads(request.body)
updated_product = product_client.update(product_id, data)
if updated_product:
return JsonResponse(updated_product[0], safe=False)
return JsonResponse({"error": "Product not found"}, status=404)
elif request.method == "DELETE":
product_client.delete(product_id)
return JsonResponse({"message": f"Product with ID {product_id} deleted"}, status=200)
Finally, create a products/urls.py
file to define your endpoints and include them in your main myproject/urls.py
file.
# products/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("products/", views.product_list_create),
path("products/<int:product_id>/", views.product_detail),
]
# myproject/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('products.urls')),
]