An example of solution to display in a template the number of online visitors in a django web site:
Create a table Visitor_Infos
First, create a table in models.py called for example: Visitor_Infos:
class Visitor_Infos(models.Model):ip_address = models.GenericIPAddressField()page_visited = models.TextField()event_date = models.DateTimeField(default=datetime.now)
Edit/create the file processor.py
Edit the context file processor.py:
from django.conf import settingsfrom .models import Visitor_Infosimport socketimport randomdef save_visitor_infos(request):context_nb_vistors = 0#----- get visitor ip -----#x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')if x_forwarded_for:ip = x_forwarded_for.split(',')[0]else:ip = request.META.get('REMOTE_ADDR')#----- check if ip adress is valid -----#try:socket.inet_aton(ip)ip_valid = Trueexcept socket.error:ip_valid = False#----- check if ip adress is valid -----#if ip_valid:do somethingreturn {"context_nb_vistors":context_nb_vistors}
Add the following lines
present_date = datetime.datetime.now()ref_date_1 = present_date - datetime.timedelta(days=1)ref_date_2 = present_date - datetime.timedelta(days=2)
Add a new table element if the visitor visits a new page:
if Visitor_Infos.objects.filter(ip_address=ip, page_visited=request.path, event_date__gte=ref_date_1).count() == 0:new_visitor_infos = Visitor_Infos(ip_address = ip,page_visited = request.path,event_date = present_date)new_visitor_infos.save()
Update the date if the visitor come back on the same page:
if Visitor_Infos.objects.filter(ip_address=ip, page_visited=request.path, event_date__gte=ref_date_1).count() == 1:visitor_infos_obj = Visitor_Infos.objects.get(ip_address=ip, page_visited=request.path, event_date__gte=ref_date_1)visitor_infos_obj.event_date = present_datevisitor_infos_obj.save()
in the file settings.py add the line 'myapp.processor.save_visitor_infos' (replace myapp by the name of your application)
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [],'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages','myapp.processor.save_visitor_infos',],},},]
Retrieve the number of visitors:
To retrieve the number of online visitor, we can for example get the number of active visitors the last 5 minutes:
ref_date = present_date - datetime.timedelta(minutes=5)context_nb_vistors = Visitor_Infos.objects.filter(event_date__gte=ref_date).values_list('ip_address', flat=True).distinct().count()return {"context_nb_vistors":context_nb_vistors}
Note: the function distinct() has been used to removed the duplicate
Show the number of visitors
Finally, just add in any template:
{{context_nb_vistors}}
processor.py file
from django.conf import settingsfrom .models import Visitor_Infosimport socketimport randomdef save_visitor_infos(request):try:#----- get visitor ip -----#x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')if x_forwarded_for:ip = x_forwarded_for.split(',')[0]else:ip = request.META.get('REMOTE_ADDR')#----- check if ip adress is valid -----#try:socket.inet_aton(ip)ip_valid = Trueexcept socket.error:ip_valid = False#----- check if ip adress is valid -----#if ip_valid:present_date = datetime.datetime.now()ref_date_1 = present_date - datetime.timedelta(days=1)ref_date_2 = present_date - datetime.timedelta(days=2)if Visitor_Infos.objects.filter(ip_address=ip, page_visited=request.path, event_date__gte=ref_date_1).count() == 0:new_visitor_infos = Visitor_Infos(ip_address = ip,page_visited = request.path,event_date = present_date)new_visitor_infos.save()if Visitor_Infos.objects.filter(ip_address=ip, page_visited=request.path, event_date__gte=ref_date_1).count() == 1:visitor_infos_obj = Visitor_Infos.objects.get(ip_address=ip, page_visited=request.path, event_date__gte=ref_date_1)visitor_infos_obj.event_date = present_datevisitor_infos_obj.save()except:passcontext_nb_vistors = 0ref_date = present_date - datetime.timedelta(minutes=5)context_nb_vistors = Visitor_Infos.objects.filter(event_date__gte=ref_date).values_list('ip_address', flat=True).distinct().count()return {"context_nb_vistors":context_nb_vistors}
References
| Links | Site |
|---|---|
| Remove duplicates in a django query | stackoverflow |
| Django: remove duplicates (group by) from queryset by related model field | stackoverflow |
| Exclude Duplicate Objects in django queryset | stackoverflow |
| The use of HTTP_X_FORWARDED_FOR and REMOTE_ADDR i | programering |
| How to Get a Client IP Address in DJANGO | pressthered |
