đī¸ đ Part 3: Activity Tracking Module Design
āĻāĻāĻžāύ⧠āĻāĻŽāϰāĻž ActivityLog model āϤā§āϰāĻŋ, Database Migration, āĻāĻŦāĻ Admin Customization āĻāϰāĻŦā§āĨ¤ āĻĒā§āϰāϤāĻŋāĻāĻŋ āϏā§āĻā§āĻĒā§ āĻĒā§āϰāĻĢā§āĻļāύāĻžāϞ āϞā§āĻā§āϞ āĻŦā§āϝāĻžāĻā§āϝāĻž + Bangla comments āĻĨāĻžāĻāĻŦā§ āϝā§āύ āĻŦāĻžāϏā§āϤāĻŦā§ apply āĻāϰāϤ⧠āĻĒāĻžāϰā§āĨ¤
â
ā§§. Designing ActivityLog model
đ¯ Goal:
āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻāϰā§āĻŽāĻāĻžāϰā§āϰ āĻāĻŽā§āĻĒāĻŋāĻāĻāĻžāϰ āĻāĻāĻāĻŋāĻāĻŋāĻāĻŋ āϞāĻ āϏāĻāϰāĻā§āώāĻŖ āĻāϰāĻž, āϝā§āĻŽāύ:
- Active window
- Website URL
- Keystrokes (optional)
- Screenshot
- App usage data
- Idle time
- Boot time (optional here; separate model recommended)
đ¨ Step 1.1 â Edit monitoring/models.py
from django.db import models
# đ Employee model import if in same file no need, else:
# from .models import Employee
class ActivityLog(models.Model):
"""
đ ActivityLog Model
āĻĒā§āϰāϤāĻŋāĻāĻŋ āϞāĻ āĻ āĻāϰā§āĻŽāĻāĻžāϰā§āϰ āĻāĻāĻāĻŋāĻāĻŋāĻāĻŋ data save āĻšāĻŦā§āĨ¤
"""
# āĻā§āύ āĻāϰā§āĻŽāĻāĻžāϰā§āϰ āϞāĻ
employee = models.ForeignKey('Employee', on_delete=models.CASCADE, related_name='activity_logs')
# āϞāĻ āĻāϰ āϏāĻŽāϝāĻŧ
timestamp = models.DateTimeField(auto_now_add=True)
# āĻā§āύ window active āĻāĻŋāϞ (āϝā§āĻŽāύ 'Google Chrome - YouTube')
active_window = models.CharField(max_length=255, blank=True, null=True)
# āϝāĻĻāĻŋ āĻāϝāĻŧā§āĻŦāϏāĻžāĻāĻā§ āĻĨāĻžāĻā§, āϤāĻžāĻšāϞ⧠URL save āĻšāĻŦā§
website_url = models.URLField(blank=True, null=True)
# Keystrokes data (optional, ethical consideration)
keystrokes = models.TextField(blank=True, null=True)
# Screenshot image
screenshot = models.ImageField(upload_to='screenshots/', blank=True, null=True)
# App usage data as JSON (example: [{"app_name":"Word","duration_min":20}])
app_usage = models.JSONField(blank=True, null=True)
# Idle time (minute)
idle_time_min = models.PositiveIntegerField(default=0)
class Meta:
ordering = ['-timestamp'] # āϏāϰā§āĻŦāĻļā§āώ āϞāĻ āĻāĻĒāϰ⧠āĻĨāĻžāĻāĻŦā§
def __str__(self):
return f"{self.employee.name} | {self.timestamp.strftime('%Y-%m-%d %H:%M:%S')}"
đ Bangla Explanation:
â
ForeignKey â āĻĒā§āϰāϤāĻŋāĻāĻŋ āϞāĻ āĻāĻāĻāĻŋ āĻāϰā§āĻŽāĻāĻžāϰā§āϰ āϏāĻžāĻĨā§ āϝā§āĻā§āϤ
â
CharField / URLField / TextField â āĻĄāĻžāĻāĻž āĻāĻžāĻāĻĒ āĻ
āύā§āϝāĻžāϝāĻŧā§
â
ImageField â screenshot save āĻšāĻŦā§ media/screenshots/ āĻĢā§āϞā§āĻĄāĻžāϰā§
â
JSONField â multiple app usage data JSON āĻāĻāĻžāϰ⧠save āĻšāĻŦā§
â
PositiveIntegerField â Idle time negative āĻšāϤ⧠āĻĒāĻžāϰ⧠āύāĻž
â
Meta ordering â Admin āĻ latest log āĻāĻĒāϰā§
đ¨ Step 1.2 â Install Pillow (ImageField requires it)
pip install Pillow
â ⧍. Migration & Database Schema Optimization
đ¨ Step 2.1 â Make Migrations
python manage.py makemigrations monitoring
đ¨ Step 2.2 â Apply Migrations
python manage.py migrate
đ Result: Database āĻ monitoring_activitylog table create āĻšāĻŦā§āĨ¤
â ā§Š. Admin Interface for Activity Logs
đ¨ Step 3.1 â Register in monitoring/admin.py
from django.contrib import admin
from .models import Employee, ActivityLog
@admin.register(ActivityLog)
class ActivityLogAdmin(admin.ModelAdmin):
# Admin table āĻ āĻā§āύ āĻā§āύ column āĻĻā§āĻāĻžāĻŦā§
list_display = ('id', 'employee', 'timestamp', 'active_window', 'website_url', 'idle_time_min')
# Search field enable āĻāϰāĻŦā§
search_fields = ('employee__name', 'active_window', 'website_url')
# Filter sidebar
list_filter = ('employee', 'timestamp')
# Readonly fields (screenshot preview)
readonly_fields = ('screenshot_preview',)
# Custom method to show screenshot preview in admin
def screenshot_preview(self, obj):
if obj.screenshot:
return f'<img src="{obj.screenshot.url}" width="200"/>'
return 'No Screenshot'
screenshot_preview.allow_tags = True
screenshot_preview.short_description = 'Screenshot Preview'
đ Bangla Explanation:
list_displayâ admin table columnssearch_fieldsâ employee āύāĻžāĻŽ, window, url search āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§list_filterâ employee āĻāĻŦāĻ timestamp filterreadonly_fields+screenshot_previewâ admin āĻ screenshot image preview
â ā§Ē. Media URL serve configuration (for local testing)
đ¨ Step 4.1 â Edit employee_monitoring/urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... your other urls
]
# Local media file serve configuration
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
đ đ Summary of Part 3
âī¸ ActivityLog Model āϤā§āϰāĻŋ āĻāϰā§āĻā§ â professional scalable design
âī¸ Migration apply āĻāϰ⧠database ready
âī¸ Admin customization â screenshots āϏāĻš logs āĻĻā§āĻāĻž āϝāĻžāĻŦā§
đ âĄī¸ Next Step:
đ Part 4: Django REST API Development
- DRF setup & configuration
- Serializer design for Employee & ActivityLog
- API endpoints to create ActivityLog (client data receive)
- Retrieve logs filtered by employee and date range
- Permission & token auth setup
đ āĻŦāϞ⧠âStart Part 4â â āϤāĻžāĻšāϞ⧠āĻāĻŽāϰāĻž API development āĻļā§āϰ⧠āĻāϰāĻŦā§, āϝāĻž Python client āĻĨā§āĻā§ data receive āĻāϰāĻŦā§āĨ¤ Step by step full code + Bangla explanation āĻĨāĻžāĻāĻŦā§āĨ¤