Skip to content

Commit df4cd5d

Browse files
JoshuaAHairstonhcientist
authored andcommitted
implemented most of the functionality of the csv button
1 parent 63a2f53 commit df4cd5d

File tree

4 files changed

+117
-74
lines changed

4 files changed

+117
-74
lines changed

teleband/dashboards/urls.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from django.urls import path
22

3-
from teleband.dashboards.views import AssignmentListView, CourseListView
4-
3+
from teleband.dashboards.views import AssignmentListView, CourseListView, csv_view
54
app_name = "dashboards"
65
urlpatterns = [
76
path("", AssignmentListView.as_view(), name="assignment_list"),
87
path("courses/", CourseListView.as_view(), name="course_list"),
8+
path("export/csv/", csv_view, name="export_csv"),
99
]

teleband/dashboards/views.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
from teleband.courses.models import Course
99
from django.contrib.auth.mixins import UserPassesTestMixin
1010

11+
import csv
12+
from django.http import HttpResponse
13+
1114

1215
class AssignmentListView(UserPassesTestMixin, generic.ListView):
1316
model = Assignment
@@ -42,3 +45,39 @@ class CourseListView(UserPassesTestMixin, generic.ListView):
4245

4346
def test_func(self):
4447
return self.request.user.is_superuser
48+
49+
50+
def csv_view(request):
51+
"""Function which generates a CSV file for download"""
52+
# select related returns a queryset that will follow foreign-key relationships. This
53+
# is a performance booster which results in a single more complex query but won't require
54+
# database queries
55+
assignments = Assignment.objects.select_related(
56+
"piece",
57+
"piece_plan",
58+
"enrollment",
59+
"enrollment__user",
60+
"enrollment__course",
61+
"enrollment__instrument",
62+
"enrollment__course__owner",
63+
"instrument",
64+
"activity",
65+
).all()
66+
67+
# Create the HttpResponse object with the appropriate CSV header
68+
response = HttpResponse(
69+
content_type="text/csv",
70+
headers={"Content-Disposition": 'attachment; filename="assignment.csv"'}
71+
)
72+
73+
writer = csv.writer(response)
74+
writer.writerow(["ID", "Course ID", "Course Name", "Piece ID", "Piece Name", "Piece Plan ID", "Piece Plan Name",
75+
"Student ID", "Student Instrument ID", "Student Instrument Name", "Assignment Activity ID",
76+
"Assignment Activity", "Assignment Instrument ID", "Assignment Instrument Name", "Submissions"])
77+
for assn in assignments:
78+
writer.writerow([assn.id, assn.enrollment.course.id, assn.enrollment.course.name, assn.piece.id,
79+
assn.piece.name, assn.piece_plan.id, assn.piece_plan, assn.enrollment.user.id,
80+
assn.enrollment.instrument.id, assn.enrollment.instrument.name, assn.activity.id,
81+
assn.activity, assn.instrument.id, assn.instrument.name, "N/A"])
82+
83+
return response

teleband/static/css/project.css

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@
1717
border-inline-start: 2px solid black;
1818
}
1919

20-
.dashboard td, .dashboard th {
20+
.dashboard td,
21+
.dashboard th {
2122
border-inline-end: 1px dashed black;
2223
}
2324

24-
.dashboard thead, .dashboard tbody{
25+
.dashboard thead,
26+
.dashboard tbody {
2527
border-block-end: 2px solid black;
2628
}
2729

2830
.dashboard tr {
2931
border-block-end: 1px dashed black;
30-
}
32+
}

teleband/templates/assignments/assignment_list.html

Lines changed: 71 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
const compositions = [];
66
const containers = [];
77
</script>
8+
<!--the app name dashboards is needed before the name set in urls file-->
9+
<a href="{% url 'dashboards:export_csv' %}" class="btn btn-primary">Download CSV</a>
810
{% comment %} https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col#usage_notes {% endcomment %}
911
<table class="dashboard">
1012
<colgroup>
@@ -64,10 +66,10 @@
6466
<th>submitted</th>
6567
</tr>
6668
</thead>
67-
69+
6870
{% for assn in assignment_list %}
6971
<tbody>
70-
{% if assn.submissions.all|length == 0 %}
72+
{% if assn.submissions.all|length == 0 %}
7173
<tr>
7274
<td>{{ assn.id }}</td>
7375
<td>{{ assn.enrollment.course.id }}</td>
@@ -85,79 +87,79 @@
8587
<td>{{ assn.instrument.name }}</td>
8688
<td colspan="8">N/A</td>
8789
</tr>
88-
{% else %}
90+
{% else %}
8991
{% for sub in assn.submissions.all %}
90-
{% for att in sub.attachments.all %}
91-
<tr>
92-
<td>{{ assn.id }}</td>
93-
<td>{{ assn.enrollment.course.id }}</td>
94-
<td>{{ assn.enrollment.course.name }}</td>
95-
<td>{{ assn.piece.id }}</td>
96-
<td>{{ assn.piece.name }}</td>
97-
<td>{{ assn.piece_plan.id }}</td>
98-
<td>{{ assn.piece_plan }}</td>
99-
<td>{{ assn.enrollment.user.id }}</td>
100-
<td>{{ assn.enrollment.instrument.id }}</td>
101-
<td>{{ assn.enrollment.instrument.name }}</td>
102-
<td>{{ assn.activity.id }}</td>
103-
<td>{{ assn.activity }}</td>
104-
<td>{{ assn.instrument.id }}</td>
105-
<td>{{ assn.instrument.name }}</td>
106-
<td>{{ sub.id }}</td>
107-
{% if assn.activity.category == 'Create' %}
108-
<td>
109-
Create, see below
110-
</td>
111-
{% else %}
112-
<td>{{ sub.content }}</td>
113-
{% endif %}
114-
<td>{{ sub.submitted }}</td>
115-
<td>{{ sub.grade }}</td>
116-
<td>{{ sub.self_grade }}</td>
117-
<td>{{ att.id }}</td>
118-
<td>{{ att.file }}</td>
119-
<td>{{ att.submitted }}</td>
120-
</tr>
121-
{% if assn.activity.category == 'Create' %}
122-
<tr>
123-
<td colspan="22">
124-
<div class="" id="flat-{{sub.id}}"></div>
125-
<script>
126-
compositions.push({{ sub.content | safe }})
127-
containers.push(document.getElementById('flat-{{sub.id}}'))
128-
</script>
129-
</td>
130-
</tr>
131-
{% endif %}
132-
{% endfor %}
92+
{% for att in sub.attachments.all %}
93+
<tr>
94+
<td>{{ assn.id }}</td>
95+
<td>{{ assn.enrollment.course.id }}</td>
96+
<td>{{ assn.enrollment.course.name }}</td>
97+
<td>{{ assn.piece.id }}</td>
98+
<td>{{ assn.piece.name }}</td>
99+
<td>{{ assn.piece_plan.id }}</td>
100+
<td>{{ assn.piece_plan }}</td>
101+
<td>{{ assn.enrollment.user.id }}</td>
102+
<td>{{ assn.enrollment.instrument.id }}</td>
103+
<td>{{ assn.enrollment.instrument.name }}</td>
104+
<td>{{ assn.activity.id }}</td>
105+
<td>{{ assn.activity }}</td>
106+
<td>{{ assn.instrument.id }}</td>
107+
<td>{{ assn.instrument.name }}</td>
108+
<td>{{ sub.id }}</td>
109+
{% if assn.activity.category == 'Create' %}
110+
<td>
111+
Create, see below
112+
</td>
113+
{% else %}
114+
<td>{{ sub.content }}</td>
115+
{% endif %}
116+
<td>{{ sub.submitted }}</td>
117+
<td>{{ sub.grade }}</td>
118+
<td>{{ sub.self_grade }}</td>
119+
<td>{{ att.id }}</td>
120+
<td>{{ att.file }}</td>
121+
<td>{{ att.submitted }}</td>
122+
</tr>
123+
{% if assn.activity.category == 'Create' %}
124+
<tr>
125+
<td colspan="22">
126+
<div class="" id="flat-{{sub.id}}"></div>
127+
<script>
128+
compositions.push({{ sub.content | safe }})
129+
containers.push(document.getElementById('flat-{{sub.id}}'))
130+
</script>
131+
</td>
132+
</tr>
133+
{% endif %}
134+
{% endfor %}
133135
{% endfor %}
134-
{% endif %}
136+
{% endif %}
135137
</tbody>
136138
{% endfor %}
137139
</table>
138140
{% endblock content %}
139141

140142
{% block custom_javascript %}
141-
<script src="https://prod.flat-cdn.com/embed-js/v2.3.0/embed.min.js"></script>
142-
<script>
143-
for (let i=0; i<compositions.length; i++) {
144-
let embed = new Flat.Embed(containers[i], {
145-
score: 'blank',
146-
embedParams: {
147-
appId: '60a51c906bcde01fc75a3ad0',
148-
layout: 'responsive',
149-
branding: false,
150-
themePrimary: '#450084',
151-
controlsDisplay: false,
152-
controlsPlay: false,
153-
controlsFullscreen: false,
154-
controlsZoom: false,
155-
controlsPrint: false,
156-
displayFirstLinePartsNames: false,
157-
toolsetId: '64be80de738efff96cc27edd',
158-
},
159-
});
160-
embed.loadJSON(compositions[i]);
161-
}
162-
</script>
143+
<script src="https://prod.flat-cdn.com/embed-js/v2.3.0/embed.min.js"></script>
144+
<script>
145+
for (let i = 0; i < compositions.length; i++) {
146+
let embed = new Flat.Embed(containers[i], {
147+
score: 'blank',
148+
embedParams: {
149+
appId: '60a51c906bcde01fc75a3ad0',
150+
layout: 'responsive',
151+
branding: false,
152+
themePrimary: '#450084',
153+
controlsDisplay: false,
154+
controlsPlay: false,
155+
controlsFullscreen: false,
156+
controlsZoom: false,
157+
controlsPrint: false,
158+
displayFirstLinePartsNames: false,
159+
toolsetId: '64be80de738efff96cc27edd',
160+
},
161+
});
162+
embed.loadJSON(compositions[i]);
163+
}
164+
</script>
163165
{% endblock custom_javascript %}

0 commit comments

Comments
 (0)