Create a Custom Django Analytic - lhmisho/django-eCommerce GitHub Wiki

Step 1: Create a app analytic

django-admin analytic

Step 2: Register the app on the settings

INSTALLED_APPS = [
    'analytic',
]

Step 3: Create the model

analytic/models.py

class ObjectViewd(models.Model):
    user    = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True) # User instance instance id
    ip_address      = models.CharField(max_length=120, blank=True, null=True)
    content_type    = models.ForeignKey(ContentType, on_delete=models.CASCADE) # User, Product, Order, Cart etc
    object_id       = models.PositiveIntegerField() # User id, Product id, Order id etc
    content_object  = GenericForeignKey('content_type','object_id') # Pordut instance
    timestamp       = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        #return "%s viewed on %s" %(self.content_object, self.timestamp)
        return (f'{self.content_object} viewed on {self.timestamp}')

    class Meta:
        "Most recent save show up first"
        ordering = ['-timestamp']
        verbose_name = 'Object viewd'
        verbose_name_plural = 'Objects viewd'


Step 4: Function for get ip form client

analytic/utils.py

def get_client_ip(request):
    x_fordwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_fordwarded_for:
        ip = x_fordwarded_for.split(",")[0]
    else:
        ip = request.META.get("REMOTE_ADDR", None)
    return ip

Step 5: Create custom signals

analytic/singnals.py

from django.dispatch import Signal
"here instance meace product id or title etc and request is for do someting for get ip of this request"
object_viewd_singnal = Signal(providing_args=['instance', 'request'])

Step 6: Object viewd mixins

analytic/mixins.py

from .singnals import object_viewd_singnal


class ObjectViewdMixin(object):
    def get_context_data(self, *args, **kwargs):
        context     = super(ObjectViewdMixin, self).get_context_data(*args, **kwargs)
        request     = self.request
        instance    = context.get('object')
        if instance:
            object_viewd_singnal.send(instance.__class__, instance=instance, request=request)
        return context

now put the mixins to all the details view where you want to track in my case i am putiing this on my product model's detail all detail view example

from analytic.mixins import ObjectViewdMixin
class ProductFeaturedDetailView(ObjectViewdMixin, DetailView):
    # geting all object form Product
    queryset = Product.objects.all().featured()
    template_name = 'products/featured-detail.html'

step 7 : Handle the object viewd signal

analytic/models.py

def object_viewd_receiver(sender, instance, request, *args, **kwargs):
    # instance.__class__
    content_type = ContentType.objects.get_for_model(sender)

    new_object_view = ObjectViewd.objects.create(
        user        = request.user,
        object_id=instance.id,
        content_type = content_type,
        ip_address=get_client_ip(request),
    )

"I send the sender along with this signal so i don't need to write the sender on connect function"

object_viewd_singnal.connect(object_viewd_receiver)