views.py 3.26 KB
Newer Older
Sarina Canelake committed
1
"""View functions for the LMS Student dashboard"""
John Hess committed
2
from django.http import Http404
David Baumgold committed
3
from edxmako.shortcuts import render_to_response
4
from django.db import connection
John Hess committed
5

6
from student.models import CourseEnrollment
John Hess committed
7
from django.contrib.auth.models import User
8

Calen Pennington committed
9

10
def dictfetchall(cursor):
John Hess committed
11
    '''Returns a list of all rows from a cursor as a column: result dict.
12 13
    Borrowed from Django documentation'''
    desc = cursor.description
14
    table = []
John Hess committed
15
    table.append([col[0] for col in desc])
David Baumgold committed
16

17 18
    # ensure response from db is a list, not a tuple (which is returned
    # by MySQL backed django instances)
Sarina Canelake committed
19
    rows_from_cursor = cursor.fetchall()
20
    table = table + [list(row) for row in rows_from_cursor]
John Hess committed
21 22
    return table

Sarina Canelake committed
23 24 25

def SQL_query_to_list(cursor, query_string):  # pylint: disable=invalid-name
    """Returns the raw result of the query"""
John Hess committed
26
    cursor.execute(query_string)
Sarina Canelake committed
27
    raw_result = dictfetchall(cursor)
John Hess committed
28
    return raw_result
29

Sarina Canelake committed
30

31 32
def dashboard(request):
    """
John Hess committed
33
    Slightly less hackish hack to show staff enrollment numbers and other
David Baumgold committed
34
    simple queries.
John Hess committed
35 36 37 38

    All queries here should be indexed and simple.  Mostly, this means don't
    touch courseware_studentmodule, as tempting as it may be.

39 40 41 42
    """
    if not request.user.is_staff:
        raise Http404

John Hess committed
43 44 45 46
    # results are passed to the template.  The template knows how to render
    # two types of results: scalars and tables.  Scalars should be represented
    # as "Visible Title": Value and tables should be lists of lists where each
    # inner list represents a single row of the table
Sarina Canelake committed
47
    results = {"scalars": {}, "tables": {}}
Calen Pennington committed
48

John Hess committed
49
    # count how many users we have
Sarina Canelake committed
50 51
    results["scalars"]["Unique Usernames"] = User.objects.filter().count()
    results["scalars"]["Activated Usernames"] = User.objects.filter(is_active=1).count()
David Baumgold committed
52

John Hess committed
53
    # count how many enrollments we have
54
    results["scalars"]["Total Enrollments Across All Courses"] = CourseEnrollment.objects.filter(is_active=1).count()
John Hess committed
55 56

    # establish a direct connection to the database (for executing raw SQL)
57
    cursor = connection.cursor()
58

John Hess committed
59 60 61 62
    # define the queries that will generate our user-facing tables
    # table queries need not take the form of raw SQL, but do in this case since
    # the MySQL backend for django isn't very friendly with group by or distinct
    table_queries = {}
63
    table_queries["course registrations (current enrollments)"] = """
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
        select
        course_id as Course,
        count(user_id) as Students
        from student_courseenrollment
        where is_active=1
        group by course_id
        order by students desc;"""
    table_queries["number of students in each number of classes"] = """
        select registrations as 'Registered for __ Classes' ,
        count(registrations) as Users
        from (select count(user_id) as registrations
               from student_courseenrollment
               where is_active=1
               group by user_id) as registrations_per_user
        group by registrations;"""
John Hess committed
79 80 81 82 83 84

    # add the result for each of the table_queries to the results object
    for query in table_queries.keys():
        cursor.execute(table_queries[query])
        results["tables"][query] = SQL_query_to_list(cursor, table_queries[query])

Sarina Canelake committed
85
    context = {"results": results}
86

Sarina Canelake committed
87
    return render_to_response("admin_dashboard.html", context)