165 lines
5.0 KiB
Python
165 lines
5.0 KiB
Python
from django.db import models
|
|
|
|
|
|
class VibnAbstractAttributionModel(models.Model):
|
|
"""
|
|
An abstract Django model that adds standard marketing attribution
|
|
(first-touch UTM parameters & referrers) to any model (e.g. User, APIClient, Customer).
|
|
|
|
To implement:
|
|
class APIClient(VibnAbstractAttributionModel):
|
|
name = models.CharField(max_length=255)
|
|
# ... other fields ...
|
|
"""
|
|
|
|
utm_source = models.CharField(
|
|
max_length=255,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Marketing channel source (e.g. twitter, google, newsletter)",
|
|
)
|
|
utm_medium = models.CharField(
|
|
max_length=255,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Marketing medium (e.g. cpc, social, organic, email)",
|
|
)
|
|
utm_campaign = models.CharField(
|
|
max_length=255,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Marketing campaign name (e.g. mcp-launch, spring-discount)",
|
|
)
|
|
utm_content = models.CharField(
|
|
max_length=255,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Specific content links or ad identifiers clicked",
|
|
)
|
|
utm_term = models.CharField(
|
|
max_length=255,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Keywords searched or paid terms clicked",
|
|
)
|
|
referrer = models.CharField(
|
|
max_length=1000,
|
|
null=True,
|
|
blank=True,
|
|
help_text="First-touch browser referrer URL (e.g. https://t.co/, https://google.com)",
|
|
)
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
def save_attribution(
|
|
self,
|
|
utm_source,
|
|
utm_medium=None,
|
|
utm_campaign=None,
|
|
utm_content=None,
|
|
utm_term=None,
|
|
referrer=None,
|
|
overwrite=False,
|
|
):
|
|
"""
|
|
Helper method to securely save marketing attribution data if it hasn't been set yet.
|
|
"""
|
|
if overwrite or not self.utm_source:
|
|
self.utm_source = utm_source
|
|
self.utm_medium = utm_medium
|
|
self.utm_campaign = utm_campaign
|
|
self.utm_content = utm_content
|
|
self.utm_term = utm_term
|
|
self.referrer = referrer
|
|
self.save(
|
|
update_fields=[
|
|
"utm_source",
|
|
"utm_medium",
|
|
"utm_campaign",
|
|
"utm_content",
|
|
"utm_term",
|
|
"referrer",
|
|
]
|
|
if self.pk
|
|
else None
|
|
)
|
|
|
|
|
|
class VibnPageview(models.Model):
|
|
"""
|
|
Vibn Pageview Tracking Model.
|
|
Tracks active user interactions and page loads in real-time,
|
|
providing fully dynamic traffic data and click timelines.
|
|
"""
|
|
|
|
user = models.ForeignKey(
|
|
"UserProfile", # Replace with your custom User model name
|
|
on_delete=models.CASCADE,
|
|
related_name="pageviews",
|
|
null=True,
|
|
blank=True,
|
|
)
|
|
session_id = models.CharField(
|
|
max_length=255, db_index=True, help_text="Unique browser session tracker ID"
|
|
)
|
|
url_path = models.CharField(
|
|
max_length=500, db_index=True, help_text="Tracked page path, e.g. /pricing"
|
|
)
|
|
referrer = models.CharField(
|
|
max_length=1000, null=True, blank=True, help_text="Traffic referrer URL"
|
|
)
|
|
|
|
# Captured UTM variables
|
|
utm_source = models.CharField(max_length=255, null=True, blank=True)
|
|
utm_medium = models.CharField(max_length=255, null=True, blank=True)
|
|
utm_campaign = models.CharField(max_length=255, null=True, blank=True)
|
|
utm_content = models.CharField(max_length=255, null=True, blank=True)
|
|
utm_term = models.CharField(max_length=255, null=True, blank=True)
|
|
|
|
# Device/Geo details
|
|
device = models.CharField(max_length=100, default="desktop")
|
|
browser = models.CharField(max_length=100, default="chrome")
|
|
country = models.CharField(max_length=100, default="US")
|
|
|
|
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
|
|
class Meta:
|
|
db_table = "vibn_pageview"
|
|
verbose_name = "Vibn Pageview"
|
|
verbose_name_plural = "Vibn Pageviews"
|
|
ordering = ["-created_at"]
|
|
|
|
|
|
class VibnEvent(models.Model):
|
|
"""
|
|
Vibn Product Event Tracking Model.
|
|
Tracks custom user conversion events (e.g. signup, connect_channel, create_campaign)
|
|
and binds them to their sessions and profiles.
|
|
"""
|
|
|
|
user = models.ForeignKey(
|
|
"UserProfile", # Replace with your custom User model name
|
|
on_delete=models.CASCADE,
|
|
related_name="events",
|
|
null=True,
|
|
blank=True,
|
|
)
|
|
session_id = models.CharField(max_length=255, db_index=True)
|
|
event_name = models.CharField(
|
|
max_length=255,
|
|
db_index=True,
|
|
help_text="Custom event name, e.g. connect_social",
|
|
)
|
|
properties = models.JSONField(
|
|
default=dict, blank=True, help_text="Custom event properties JSON"
|
|
)
|
|
|
|
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
|
|
class Meta:
|
|
db_table = "vibn_event"
|
|
verbose_name = "Vibn Event"
|
|
verbose_name_plural = "Vibn Events"
|
|
ordering = ["-created_at"]
|