Skip to main content

Django Integration

Django-specific integration patterns and best practices.

Django Settings

Required Settings

# settings.py

# SVA OAuth Configuration
SVA_OAUTH_BASE_URL = os.getenv('SVA_OAUTH_BASE_URL', 'https://auth.getsva.com')
SVA_OAUTH_CLIENT_ID = os.getenv('SVA_OAUTH_CLIENT_ID')
SVA_OAUTH_CLIENT_SECRET = os.getenv('SVA_OAUTH_CLIENT_SECRET')
SVA_OAUTH_REDIRECT_URI = os.getenv('SVA_OAUTH_REDIRECT_URI')
SVA_DATA_TOKEN_SECRET = os.getenv('SVA_DATA_TOKEN_SECRET')

# Optional
SVA_OAUTH_SCOPES = os.getenv('SVA_OAUTH_SCOPES', 'openid email profile')
SVA_DATA_TOKEN_ALGORITHM = os.getenv('SVA_DATA_TOKEN_ALGORITHM', 'HS256')
SVA_OAUTH_SUCCESS_REDIRECT = '/dashboard/'
SVA_OAUTH_ERROR_REDIRECT = '/login/'
SVA_OAUTH_LOGOUT_REDIRECT = '/'
SVA_OAUTH_LOGIN_URL = '/oauth/login/'

INSTALLED_APPS

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions', # Required!
'django.contrib.messages',
'django.contrib.staticfiles',
# ... your apps
'sva_oauth_client',
]

MIDDLEWARE

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', # Must be before TokenRefreshMiddleware
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# ... your middleware
'sva_oauth_client.middleware.TokenRefreshMiddleware', # Add this
]

URL Configuration

Main URLs

# urls.py
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('oauth/', include('sva_oauth_client.urls')), # OAuth URLs
# ... your URLs
]

App URLs

# myapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
path('dashboard/', views.dashboard, name='dashboard'),
path('profile/', views.profile, name='profile'),
]

View Integration

Function-Based Views

# views.py
from django.shortcuts import render, redirect
from sva_oauth_client.decorators import sva_oauth_required, sva_blocks_required
from sva_oauth_client.utils import get_sva_claims, is_authenticated

def home(request):
"""Home page"""
context = {
'is_authenticated': is_authenticated(request.session),
}
return render(request, 'home.html', context)

@sva_oauth_required
def dashboard(request):
"""Protected dashboard"""
claims = get_sva_claims(request)
return render(request, 'dashboard.html', {'claims': claims})

@sva_blocks_required('email', 'name')
def profile(request):
"""Profile requiring email and name"""
claims = get_sva_claims(request)
return render(request, 'profile.html', {'claims': claims})

Class-Based Views

# views.py
from django.views import View
from django.utils.decorators import method_decorator
from django.shortcuts import render
from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_sva_claims

@method_decorator(sva_oauth_required, name='dispatch')
class DashboardView(View):
def get(self, request):
claims = get_sva_claims(request)
return render(request, 'dashboard.html', {'claims': claims})

Template Integration

Check Authentication

<!-- templates/base.html -->
{% if request.session.sva_oauth_access_token %}
<a href="{% url 'sva_oauth_client:logout' %}">Logout</a>
{% else %}
<a href="{% url 'sva_oauth_client:login' %}">Sign In</a>
{% endif %}

Display User Data

<!-- templates/dashboard.html -->
{% if claims.email %}
<p>Email: {{ claims.email }}</p>
{% endif %}

{% if claims.name %}
<p>Name: {{ claims.name }}</p>
{% endif %}

Login Button

<!-- templates/login.html -->
<a href="{% url 'sva_oauth_client:login' %}" class="btn btn-primary">
Sign In with SVA
</a>

Django REST Framework

API Views

# api/views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_sva_claims

@api_view(['GET'])
@sva_oauth_required
def api_user_info(request):
"""API endpoint for user information"""
claims = get_sva_claims(request)

return Response({
'email': claims.get('email'),
'name': claims.get('name'),
'username': claims.get('username'),
})

ViewSets

# api/views.py
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_sva_claims

class UserViewSet(ViewSet):
@action(detail=False, methods=['get'])
@sva_oauth_required
def profile(self, request):
"""Get user profile"""
claims = get_sva_claims(request)
return Response(claims)

Django Forms

Pre-fill Forms

# forms.py
from django import forms

class RegistrationForm(forms.Form):
email = forms.EmailField()
first_name = forms.CharField()
last_name = forms.CharField()
phone = forms.CharField(required=False)

# views.py
@sva_oauth_required
def registration(request):
"""Registration form pre-filled with OAuth data"""
claims = get_sva_claims(request)

initial = {}
if 'email' in claims:
initial['email'] = claims['email']
if 'name' in claims:
name_parts = claims['name'].split(' ', 1)
initial['first_name'] = name_parts[0]
if len(name_parts) > 1:
initial['last_name'] = name_parts[1]
if 'phone' in claims:
initial['phone'] = claims['phone']

form = RegistrationForm(initial=initial)

if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
# Process form
pass

return render(request, 'registration.html', {'form': form})

Django Messages

Success Messages

from django.contrib import messages

@sva_oauth_required
def my_view(request):
claims = get_sva_claims(request)
messages.success(request, f'Welcome, {claims.get("name", "User")}!')
return render(request, 'dashboard.html', {'claims': claims})

Error Messages

from django.contrib import messages
from sva_oauth_client.utils import get_sva_claims
from sva_oauth_client.client import SVATokenError

@sva_oauth_required
def my_view(request):
try:
claims = get_sva_claims(request)
except SVATokenError:
messages.error(request, 'Your session has expired. Please sign in again.')
return redirect('sva_oauth_client:login')

Django User Model Integration

Create Django User from OAuth

from django.contrib.auth.models import User
from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_sva_claims

@sva_oauth_required
def sync_user(request):
"""Sync OAuth user with Django User model"""
claims = get_sva_claims(request)
email = claims.get('email')

if not email:
return redirect('sva_oauth_client:login')

# Get or create user
user, created = User.objects.get_or_create(
email=email,
defaults={
'username': email,
'first_name': claims.get('name', '').split()[0] if claims.get('name') else '',
}
)

# Log in Django user
from django.contrib.auth import login
login(request, user)

return redirect('/dashboard/')

Django Admin Integration

Custom Admin Actions

# admin.py
from django.contrib import admin
from sva_oauth_client.utils import is_authenticated

@admin.action(description='Check OAuth status')
def check_oauth_status(modeladmin, request, queryset):
"""Check OAuth authentication status"""
for obj in queryset:
# Check OAuth status
pass

Testing

Test OAuth Flow

# tests.py
from django.test import TestCase, Client
from django.urls import reverse

class OAuthTestCase(TestCase):
def setUp(self):
self.client = Client()

def test_login_redirect(self):
"""Test login redirect"""
response = self.client.get('/dashboard/')
self.assertRedirects(response, '/oauth/login/')

Next Steps