62 lines
2.0 KiB
Python
62 lines
2.0 KiB
Python
import logging
|
|
|
|
from rest_framework import serializers
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class VibnAttributionCaptureMixin:
|
|
"""
|
|
A Django REST Framework ViewSet/APIView mixin that automatically
|
|
extracts marketing attribution fields (UTMs, referrer) from incoming
|
|
request payloads or HTTP headers and binds them to the saving object.
|
|
|
|
Compatible with any Django REST Framework serializer.
|
|
"""
|
|
|
|
def extract_attribution_data(self, request):
|
|
"""
|
|
Extracts UTM and referrer keys from request data, falling back
|
|
to request headers if required.
|
|
"""
|
|
# Try request payload first
|
|
data = request.data or {}
|
|
|
|
utm_source = data.get("utm_source")
|
|
utm_medium = data.get("utm_medium")
|
|
utm_campaign = data.get("utm_campaign")
|
|
utm_content = data.get("utm_content")
|
|
utm_term = data.get("utm_term")
|
|
|
|
# Capture Referrer from payload or fallback to HTTP headers
|
|
referrer = data.get("referrer")
|
|
if not referrer:
|
|
referrer = request.META.get("HTTP_REFERER")
|
|
|
|
return {
|
|
"utm_source": utm_source,
|
|
"utm_medium": utm_medium,
|
|
"utm_campaign": utm_campaign,
|
|
"utm_content": utm_content,
|
|
"utm_term": utm_term,
|
|
"referrer": referrer,
|
|
}
|
|
|
|
def perform_create(self, serializer):
|
|
"""
|
|
In DRF ViewSets, overrides perform_create to automatically inject
|
|
attribution fields directly into the saved model instance.
|
|
"""
|
|
attrib_data = self.extract_attribution_data(self.request)
|
|
|
|
# Save serializer with attribution params injected as overrides
|
|
instance = serializer.save(
|
|
**{k: v for k, v in attrib_data.items() if v is not None}
|
|
)
|
|
|
|
logger.info(
|
|
f"VibnTracker: Saved attribution data to {instance.__class__.__name__} "
|
|
f"(Source: {attrib_data['utm_source']}, Campaign: {attrib_data['utm_campaign']})"
|
|
)
|
|
return instance
|