From 2f5e1b9cc0c15e742570d3a4aef15067d9abfd7e Mon Sep 17 00:00:00 2001 From: John Hess Date: Thu, 28 Feb 2013 10:54:57 -0500 Subject: [PATCH 1/2] Readable admin_dashboard --- lms/djangoapps/dashboard/views.py | 68 ++++++++++++++++++++++-------- lms/templates/admin_dashboard.html | 39 +++++++++++++++++ 2 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 lms/templates/admin_dashboard.html diff --git a/lms/djangoapps/dashboard/views.py b/lms/djangoapps/dashboard/views.py index f5929f241b..9f2a69c4c0 100644 --- a/lms/djangoapps/dashboard/views.py +++ b/lms/djangoapps/dashboard/views.py @@ -1,39 +1,71 @@ # Create your views here. import json from datetime import datetime -from django.http import HttpResponse, Http404 +from django.http import Http404 +from mitxmako.shortcuts import render_to_response + +from student.models import CourseEnrollment, CourseEnrollmentAllowed +from django.contrib.auth.models import User def dictfetchall(cursor): - '''Returns all rows from a cursor as a dict. + '''Returns a list of all rows from a cursor as a column: result dict. Borrowed from Django documentation''' desc = cursor.description - return [ - dict(zip([col[0] for col in desc], row)) - for row in cursor.fetchall() - ] + table=[] + table.append([col[0] for col in desc]) + table = table + cursor.fetchall() + print "Table: " + str(table) + return table + +def SQL_query_to_list(cursor, query_string): + cursor.execute(query_string) + raw_result=dictfetchall(cursor) + print raw_result + return raw_result def dashboard(request): """ - Quick hack to show staff enrollment numbers. This should be - replaced with a real dashboard later. This version is a short-term - bandaid for the next couple weeks. + Slightly less hackish hack to show staff enrollment numbers and other + simple queries. + + All queries here should be indexed and simple. Mostly, this means don't + touch courseware_studentmodule, as tempting as it may be. + """ if not request.user.is_staff: raise Http404 - queries = [] - queries.append("select count(user_id) as students, course_id from student_courseenrollment group by course_id order by students desc;") - queries.append("select count(distinct user_id) as unique_students from student_courseenrollment;") - queries.append("select registrations, count(registrations) from (select count(user_id) as registrations from student_courseenrollment group by user_id) as registrations_per_user group by registrations;") + # 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 + results = {"scalars":{},"tables":{}} + # count how many users we have + results["scalars"]["Unique Usernames"]=User.objects.filter().count() + results["scalars"]["Activated Usernames"]=User.objects.filter(is_active=1).count() + + # count how many enrollments we have + results["scalars"]["Total Enrollments Across All Courses"]=CourseEnrollment.objects.count() + + # establish a direct connection to the database (for executing raw SQL) from django.db import connection cursor = connection.cursor() - results = [] - for query in queries: - cursor.execute(query) - results.append(dictfetchall(cursor)) + # 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 = {} + table_queries["course enrollments"]="select count(user_id) as students, course_id from student_courseenrollment group by course_id order by students desc;" + table_queries["number of students in each number of classes"]="select registrations, count(registrations) from (select count(user_id) as registrations from student_courseenrollment group by user_id) as registrations_per_user group by registrations;" - return HttpResponse(json.dumps(results, indent=4)) + # 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]) + + context={"results":results} + + return render_to_response("admin_dashboard.html",context) diff --git a/lms/templates/admin_dashboard.html b/lms/templates/admin_dashboard.html new file mode 100644 index 0000000000..9731fd71e9 --- /dev/null +++ b/lms/templates/admin_dashboard.html @@ -0,0 +1,39 @@ +<%namespace name='static' file='static_content.html'/> + +<%inherit file="main.html" /> + +
+ +
+ +
+

edX-wide Summary

+ + % for key in results["scalars"]: + + + + + % endfor +
${key}${results["scalars"][key]}
+
+ + % for table in results["tables"]: +
+
+

${table}

+ + % for row in results["tables"][table]: + + % for column in row: + + % endfor + + % endfor +
${column}
+ +
+ % endfor +
+
+ From 02e30f50726d630ecf1ed3a3d9571aa2418c18e6 Mon Sep 17 00:00:00 2001 From: John Hess Date: Thu, 28 Feb 2013 11:11:57 -0500 Subject: [PATCH 2/2] Cleaned up admin_dashboard code and template --- lms/djangoapps/dashboard/views.py | 17 ++++++++++++++--- lms/templates/admin_dashboard.html | 7 ++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lms/djangoapps/dashboard/views.py b/lms/djangoapps/dashboard/views.py index 9f2a69c4c0..e74d462432 100644 --- a/lms/djangoapps/dashboard/views.py +++ b/lms/djangoapps/dashboard/views.py @@ -24,7 +24,6 @@ def SQL_query_to_list(cursor, query_string): print raw_result return raw_result - def dashboard(request): """ Slightly less hackish hack to show staff enrollment numbers and other @@ -58,8 +57,20 @@ def dashboard(request): # 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 = {} - table_queries["course enrollments"]="select count(user_id) as students, course_id from student_courseenrollment group by course_id order by students desc;" - table_queries["number of students in each number of classes"]="select registrations, count(registrations) from (select count(user_id) as registrations from student_courseenrollment group by user_id) as registrations_per_user group by registrations;" + table_queries["course enrollments"]= \ + "select "+ \ + "course_id as Course, "+ \ + "count(user_id) as Students " + \ + "from student_courseenrollment "+ \ + "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 "+ \ + "group by user_id) as registrations_per_user "+ \ + "group by registrations;" # add the result for each of the table_queries to the results object for query in table_queries.keys(): diff --git a/lms/templates/admin_dashboard.html b/lms/templates/admin_dashboard.html index 9731fd71e9..6a903a3f94 100644 --- a/lms/templates/admin_dashboard.html +++ b/lms/templates/admin_dashboard.html @@ -23,7 +23,12 @@

${table}

- % for row in results["tables"][table]: + + % for column in results["tables"][table][0]: + + % endfor + + % for row in results["tables"][table][1:]: % for column in row:
${column}
${column}