This commit is contained in:
Dmitriy
2025-06-23 01:24:34 +03:00
commit 60b4e0e839
303 changed files with 35737 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

20
analytics/admin.py Normal file
View File

@ -0,0 +1,20 @@
from django.contrib import admin
from .models import CourseAnalytics, InstructorAnalytics, StudentAnalytics
@admin.register(CourseAnalytics)
class CourseAnalyticsAdmin(admin.ModelAdmin):
list_display = ('course', 'total_students', 'average_progress', 'completion_rate', 'revenue', 'created_at', 'updated_at')
list_filter = ('created_at', 'updated_at')
search_fields = ('course__title',)
@admin.register(InstructorAnalytics)
class InstructorAnalyticsAdmin(admin.ModelAdmin):
list_display = ('instructor', 'total_lessons', 'total_students', 'average_rating', 'completion_rate', 'created_at', 'updated_at')
list_filter = ('created_at', 'updated_at')
search_fields = ('instructor__profile__user__username', 'instructor__profile__user__email')
@admin.register(StudentAnalytics)
class StudentAnalyticsAdmin(admin.ModelAdmin):
list_display = ('student', 'total_lessons', 'attendance_rate', 'average_grade', 'created_at', 'updated_at')
list_filter = ('created_at', 'updated_at')
search_fields = ('student__profile__user__username', 'student__profile__user__email')

View File

@ -0,0 +1,56 @@
# Generated by Django 5.0.2 on 2025-06-10 20:05
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('instructor', '0001_initial'),
('schedule', '0003_alter_lesson_options_remove_lesson_lesson_type_and_more'),
('student', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='CourseAnalytics',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('total_students', models.IntegerField(default=0)),
('average_progress', models.DecimalField(decimal_places=2, default=0, max_digits=5)),
('completion_rate', models.DecimalField(decimal_places=2, default=0, max_digits=5)),
('revenue', models.DecimalField(decimal_places=2, default=0, max_digits=10)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='schedule.course')),
],
),
migrations.CreateModel(
name='InstructorAnalytics',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('total_lessons', models.IntegerField(default=0)),
('total_students', models.IntegerField(default=0)),
('average_rating', models.DecimalField(decimal_places=2, default=5.0, max_digits=3)),
('completion_rate', models.DecimalField(decimal_places=2, default=0, max_digits=5)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('instructor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='instructor.instructor')),
],
),
migrations.CreateModel(
name='StudentAnalytics',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('total_lessons', models.IntegerField(default=0)),
('attendance_rate', models.DecimalField(decimal_places=2, default=0, max_digits=5)),
('average_grade', models.DecimalField(decimal_places=2, default=0, max_digits=3)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='student.student')),
],
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 5.0.2 on 2025-06-10 20:24
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('analytics', '0001_initial'),
('course', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='courseanalytics',
name='course',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='course.course'),
),
]

View File

41
analytics/models.py Normal file
View File

@ -0,0 +1,41 @@
from django.db import models
from django.contrib.auth.models import User
from course.models import Course
from schedule.models import Lesson
from instructor.models import Instructor
from student.models import Student
class CourseAnalytics(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
total_students = models.IntegerField(default=0)
average_progress = models.DecimalField(max_digits=5, decimal_places=2, default=0)
completion_rate = models.DecimalField(max_digits=5, decimal_places=2, default=0)
revenue = models.DecimalField(max_digits=10, decimal_places=2, default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f"Аналитика курса {self.course.title}"
class InstructorAnalytics(models.Model):
instructor = models.ForeignKey(Instructor, on_delete=models.CASCADE)
total_lessons = models.IntegerField(default=0)
total_students = models.IntegerField(default=0)
average_rating = models.DecimalField(max_digits=3, decimal_places=2, default=5.00)
completion_rate = models.DecimalField(max_digits=5, decimal_places=2, default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f"Аналитика инструктора {self.instructor}"
class StudentAnalytics(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE)
total_lessons = models.IntegerField(default=0)
attendance_rate = models.DecimalField(max_digits=5, decimal_places=2, default=0)
average_grade = models.DecimalField(max_digits=3, decimal_places=2, default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f"Аналитика студента {self.student}"

13
analytics/urls.py Normal file
View File

@ -0,0 +1,13 @@
from django.urls import path
from . import views
app_name = 'analytics'
urlpatterns = [
path('', views.analytics_dashboard, name='analytics_dashboard'),
path('courses/', views.course_analytics, name='course_analytics'),
path('instructors/', views.instructor_analytics, name='instructor_analytics'),
path('students/', views.student_analytics, name='student_analytics'),
path('reports/', views.generate_reports, name='generate_reports'),
path('export/', views.export_data, name='export_data'),
]

78
analytics/views.py Normal file
View File

@ -0,0 +1,78 @@
from django.shortcuts import render
from django.contrib.auth.decorators import login_required, user_passes_test
from .models import CourseAnalytics, InstructorAnalytics, StudentAnalytics
from schedule.models import Course, Lesson, LessonEnrollment
from instructor.models import Instructor
from student.models import Student
import json
from django.http import HttpResponse
def is_admin(user):
return user.profile.user_type == 'admin'
@login_required
@user_passes_test(is_admin)
def analytics_dashboard(request):
course_analytics = CourseAnalytics.objects.all()
instructor_analytics = InstructorAnalytics.objects.all()
student_analytics = StudentAnalytics.objects.all()
return render(request, 'analytics/dashboard.html', {
'course_analytics': course_analytics,
'instructor_analytics': instructor_analytics,
'student_analytics': student_analytics
})
@login_required
@user_passes_test(is_admin)
def course_analytics(request):
courses = Course.objects.all()
analytics = CourseAnalytics.objects.filter(course__in=courses)
return render(request, 'analytics/course_analytics.html', {
'courses': courses,
'analytics': analytics
})
@login_required
@user_passes_test(is_admin)
def instructor_analytics(request):
instructors = Instructor.objects.all()
analytics = InstructorAnalytics.objects.filter(instructor__in=instructors)
return render(request, 'analytics/instructor_analytics.html', {
'instructors': instructors,
'analytics': analytics
})
@login_required
@user_passes_test(is_admin)
def student_analytics(request):
students = Student.objects.all()
analytics = StudentAnalytics.objects.filter(student__in=students)
return render(request, 'analytics/student_analytics.html', {
'students': students,
'analytics': analytics
})
@login_required
@user_passes_test(is_admin)
def generate_reports(request):
# Здесь будет логика генерации отчетов
return render(request, 'analytics/reports.html')
@login_required
@user_passes_test(is_admin)
def export_data(request):
data = {
'courses': list(Course.objects.values()),
'instructors': list(Instructor.objects.values()),
'students': list(Student.objects.values()),
'lessons': list(Lesson.objects.values()),
'enrollments': list(LessonEnrollment.objects.values())
}
response = HttpResponse(
json.dumps(data, ensure_ascii=False),
content_type='application/json'
)
response['Content-Disposition'] = 'attachment; filename="analytics_data.json"'
return response