Commit 8d82a1f92eb096559f1932c248ad4501b57c6607
1 parent
5456f053
Exists in
master
and in
3 other branches
made progress on template using formsets, still has to send data through URL to …
…the other view and find a good way to select resources dynamically
Showing
6 changed files
with
132 additions
and
49 deletions
Show diff stats
reports/forms.py
@@ -2,6 +2,13 @@ from django import forms | @@ -2,6 +2,13 @@ from django import forms | ||
2 | from django.utils.translation import ugettext_lazy as _ | 2 | from django.utils.translation import ugettext_lazy as _ |
3 | import datetime | 3 | import datetime |
4 | 4 | ||
5 | +from django.forms.formsets import BaseFormSet | ||
6 | + | ||
7 | +class ResourceAndTagForm(forms.Form): | ||
8 | + | ||
9 | + resource = forms.ChoiceField(label=_("Resources"), required=True) | ||
10 | + tag = forms.ChoiceField(label=_('Tag')) | ||
11 | + | ||
5 | 12 | ||
6 | 13 | ||
7 | class CreateInteractionReportForm(forms.Form): | 14 | class CreateInteractionReportForm(forms.Form): |
@@ -17,13 +24,14 @@ class CreateInteractionReportForm(forms.Form): | @@ -17,13 +24,14 @@ class CreateInteractionReportForm(forms.Form): | ||
17 | 24 | ||
18 | def __init__(self, *args, **kwargs): | 25 | def __init__(self, *args, **kwargs): |
19 | super(CreateInteractionReportForm, self).__init__(*args, **kwargs) | 26 | super(CreateInteractionReportForm, self).__init__(*args, **kwargs) |
20 | - | ||
21 | initial = kwargs['initial'] | 27 | initial = kwargs['initial'] |
22 | topics = list(initial['topic']) | 28 | topics = list(initial['topic']) |
23 | self.subject = initial['subject'] #so we can check date cleaned data | 29 | self.subject = initial['subject'] #so we can check date cleaned data |
24 | self.fields['topic'].choices = [(topic.id, topic.name) for topic in topics] | 30 | self.fields['topic'].choices = [(topic.id, topic.name) for topic in topics] |
25 | self.fields['topic'].choices.append((_("All"), _("All"))) | 31 | self.fields['topic'].choices.append((_("All"), _("All"))) |
26 | 32 | ||
33 | + | ||
34 | + | ||
27 | def clean_init_date(self): | 35 | def clean_init_date(self): |
28 | init_date = self.cleaned_data.get('init_date') | 36 | init_date = self.cleaned_data.get('init_date') |
29 | if init_date < self.subject.init_date: | 37 | if init_date < self.subject.init_date: |
@@ -32,6 +40,6 @@ class CreateInteractionReportForm(forms.Form): | @@ -32,6 +40,6 @@ class CreateInteractionReportForm(forms.Form): | ||
32 | 40 | ||
33 | def clean_end_date(self): | 41 | def clean_end_date(self): |
34 | end_date = self.cleaned_data.get('init_date') | 42 | end_date = self.cleaned_data.get('init_date') |
35 | - if end_date > self.subject.init_date: | ||
36 | - self._errors['end_date'] = [_('This date should be right or before ' + str(self.subject.init_date) + ', which is when the subject finishes. ')] | 43 | + if end_date > self.subject.end_date: |
44 | + self._errors['end_date'] = [_('This date should be right or before ' + str(self.subject.end_date) + ', which is when the subject finishes. ')] | ||
37 | return end_date | 45 | return end_date |
38 | \ No newline at end of file | 46 | \ No newline at end of file |
reports/templates/reports/_form.html
1 | {% load widget_tweaks static i18n %} | 1 | {% load widget_tweaks static i18n %} |
2 | 2 | ||
3 | <form action="" method="post">{% csrf_token %} | 3 | <form action="" method="post">{% csrf_token %} |
4 | + <p>{% trans "General Parameters" %}</p><hr> | ||
4 | {% for field in form %} | 5 | {% for field in form %} |
5 | - {% if field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date' %} | ||
6 | - <label> {{field.label}} </label> | ||
7 | - {% render_field field class='form-control date-picker' %} | ||
8 | - | ||
9 | - {% else %} | ||
10 | - <label> {{field.label}} </label> | ||
11 | - {% render_field field class='form-control' %} | ||
12 | - {% endif %} | ||
13 | - | ||
14 | - {% if field.errors %} | ||
15 | - <div class="row"> | ||
16 | - </br> | ||
17 | - <div class="alert alert-danger alert-dismissible" role="alert"> | ||
18 | - <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | ||
19 | - <span aria-hidden="true">×</span> | ||
20 | - </button> | ||
21 | - <ul> | ||
22 | - {% for error in field.errors %} | ||
23 | - <li>{{ error }}</li> | ||
24 | - {% endfor %} | ||
25 | - </ul> | ||
26 | - </div> | ||
27 | - </div> | 6 | + {% if field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date' %} |
7 | + <label> {{field.label}} </label> | ||
8 | + {% render_field field class='form-control date-picker' %} | ||
9 | + | ||
10 | + | ||
11 | + {% elif field.auto_id == 'id_from_mural' %} | ||
12 | + <p>{% trans "Data Source" %}</p><hr> | ||
13 | + <label> {{field.label}} </label> | ||
14 | + {% render_field field class='form-control' %} | ||
15 | + {% else %} | ||
16 | + <label> {{field.label}} </label> | ||
17 | + {% render_field field class='form-control' %} | ||
28 | {% endif %} | 18 | {% endif %} |
19 | + | ||
20 | + {% if field.errors %} | ||
21 | + <div class="row"> | ||
22 | + </br> | ||
23 | + <div class="alert alert-danger alert-dismissible" role="alert"> | ||
24 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | ||
25 | + <span aria-hidden="true">×</span> | ||
26 | + </button> | ||
27 | + <ul> | ||
28 | + {% for error in field.errors %} | ||
29 | + <li>{{ error }}</li> | ||
30 | + {% endfor %} | ||
31 | + </ul> | ||
32 | + </div> | ||
33 | + </div> | ||
34 | + {% endif %} | ||
29 | {% endfor %} | 35 | {% endfor %} |
36 | + | ||
37 | + <!---Adding the selector --> | ||
38 | + <div class="panel-group" id="resources_accordion" role="tablist" aria-multiselectable="true"> | ||
39 | + <div class="panel panel-info"> | ||
40 | + <div class="panel-heading"> | ||
41 | + <div class="row"> | ||
42 | + <div class="col-md-12"> | ||
43 | + <a data-parent="#resources_accordion" data-toggle="collapse" href="#resources"> | ||
44 | + <h4 class="panel-title"> | ||
45 | + <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button><label for="resources">{% trans "Interaction with resources" %}</label> | ||
46 | + </h4> | ||
47 | + </a> | ||
48 | + </div> | ||
49 | + </div> | ||
50 | + </div> | ||
51 | + | ||
52 | + <div id="resources" class="panel-collapse collapse"> | ||
53 | + {{ resource_tag_formset.management_form }} | ||
54 | + | ||
55 | + {% for resource_tag_form in resource_tag_formset %} | ||
56 | + <div class="resource-tag-formset"> | ||
57 | + {% for field in resource_tag_form %} | ||
58 | + <label>{{field.label}}</label> | ||
59 | + {% render_field field class="form-control" %} | ||
60 | + {% endfor %} | ||
61 | + </div> | ||
62 | + {% endfor %} | ||
63 | + </div> | ||
64 | + </div> | ||
65 | + </div> | ||
66 | + | ||
30 | <div class="row text-center"> | 67 | <div class="row text-center"> |
31 | <input type="submit" value="Search" class="btn btn-success btn-raised" /> | 68 | <input type="submit" value="Search" class="btn btn-success btn-raised" /> |
32 | </div> | 69 | </div> |
33 | </form> | 70 | </form> |
71 | + | ||
72 | + |
reports/templates/reports/create.html
@@ -11,6 +11,12 @@ | @@ -11,6 +11,12 @@ | ||
11 | {% breadcrumb 'analytics' '' %} | 11 | {% breadcrumb 'analytics' '' %} |
12 | {% endblock %} | 12 | {% endblock %} |
13 | 13 | ||
14 | +{% block javascript %} | ||
15 | + {{block.super}} | ||
16 | + <script type="text/javascript" src="{% static "js/jquery.formset.js" %} "></script> | ||
17 | + | ||
18 | +{% endblock javascript %} | ||
19 | + | ||
14 | {% block content %} | 20 | {% block content %} |
15 | 21 | ||
16 | <div class="panel panel-info topic-panel"> | 22 | <div class="panel panel-info topic-panel"> |
@@ -41,5 +47,11 @@ | @@ -41,5 +47,11 @@ | ||
41 | 47 | ||
42 | {% include "reports/_form.html" %} | 48 | {% include "reports/_form.html" %} |
43 | 49 | ||
44 | - | 50 | + <script type="text/javascript" src="{% static "reports/js/report.js" %}"></script> |
51 | + <script> | ||
52 | + $('.resource-tag-formset').formset({ | ||
53 | + addText: 'add data source', | ||
54 | + deleteText: 'remove data source' | ||
55 | + }); | ||
56 | + </script> | ||
45 | {% endblock content %} | 57 | {% endblock content %} |
46 | \ No newline at end of file | 58 | \ No newline at end of file |
reports/templates/reports/view.html
@@ -6,9 +6,9 @@ | @@ -6,9 +6,9 @@ | ||
6 | 6 | ||
7 | {% block breadcrumbs %} | 7 | {% block breadcrumbs %} |
8 | {{ block.super }} | 8 | {{ block.super }} |
9 | - {% breadcrumb view.subject.category 'subjects:cat_view' view.subject.category.slug %} | ||
10 | - {% breadcrumb view.subject 'subjects:view' view.subject.slug %} | ||
11 | - {% breadcrumb 'analytics' '' %} | 9 | + {% breadcrumb subject.category 'subjects:cat_view' subject.category.slug %} |
10 | + {% breadcrumb subject 'subjects:view' subject.slug %} | ||
11 | + {% breadcrumb 'Analytics' '' %} | ||
12 | {% endblock %} | 12 | {% endblock %} |
13 | 13 | ||
14 | {% block content %} | 14 | {% block content %} |
@@ -65,10 +65,6 @@ | @@ -65,10 +65,6 @@ | ||
65 | <ul id="report-info"> | 65 | <ul id="report-info"> |
66 | <li> {{data.values|length}} {% trans "register(s)" %} </li> | 66 | <li> {{data.values|length}} {% trans "register(s)" %} </li> |
67 | <li> | 67 | <li> |
68 | - <i class="fa fa-download" aria-hidden="true"></i> {% trans "Variable Descriptions" %} | ||
69 | - | ||
70 | - </li> | ||
71 | - <li> | ||
72 | <i class="fa fa-download" aria-hidden="true"></i> {% trans "Interactions Data" %} | 68 | <i class="fa fa-download" aria-hidden="true"></i> {% trans "Interactions Data" %} |
73 | </li> | 69 | </li> |
74 | </ul> | 70 | </ul> |
reports/views.py
@@ -13,9 +13,11 @@ from django.db.models import Q | @@ -13,9 +13,11 @@ from django.db.models import Q | ||
13 | from django.contrib.auth.mixins import LoginRequiredMixin | 13 | from django.contrib.auth.mixins import LoginRequiredMixin |
14 | from datetime import datetime, date | 14 | from datetime import datetime, date |
15 | from subjects.models import Subject | 15 | from subjects.models import Subject |
16 | -from .forms import CreateInteractionReportForm | 16 | +from .forms import CreateInteractionReportForm, ResourceAndTagForm |
17 | from log.models import Log | 17 | from log.models import Log |
18 | +from topics.models import Resource | ||
18 | 19 | ||
20 | +from django.forms import formset_factory | ||
19 | 21 | ||
20 | class ReportView(LoginRequiredMixin, generic.FormView): | 22 | class ReportView(LoginRequiredMixin, generic.FormView): |
21 | template_name = "reports/create.html" | 23 | template_name = "reports/create.html" |
@@ -40,7 +42,24 @@ class ReportView(LoginRequiredMixin, generic.FormView): | @@ -40,7 +42,24 @@ class ReportView(LoginRequiredMixin, generic.FormView): | ||
40 | subject = Subject.objects.get(id=self.request.GET['subject_id']) | 42 | subject = Subject.objects.get(id=self.request.GET['subject_id']) |
41 | 43 | ||
42 | context['subject'] = subject | 44 | context['subject'] = subject |
45 | + | ||
46 | + topics = subject.topic_subject.all() | ||
47 | + #get all resources associated with topics | ||
48 | + resources = [] | ||
49 | + tags = [] | ||
50 | + for topic in topics: | ||
51 | + resources_set = topic.resource_topic.all() | ||
52 | + for resource in resources_set: | ||
53 | + for tag in resource.tags.all(): | ||
54 | + tags.append(tag) | ||
55 | + resources.append(resource) | ||
56 | + context['resources'] = resources | ||
57 | + context['tags'] = tags | ||
43 | 58 | ||
59 | + | ||
60 | + #set formset | ||
61 | + resourceTagFormSet = formset_factory(ResourceAndTagForm, extra= 1) | ||
62 | + context['resource_tag_formset'] = resourceTagFormSet | ||
44 | return context | 63 | return context |
45 | 64 | ||
46 | def get_success_url(self): | 65 | def get_success_url(self): |
@@ -65,8 +84,9 @@ class ReportView(LoginRequiredMixin, generic.FormView): | @@ -65,8 +84,9 @@ class ReportView(LoginRequiredMixin, generic.FormView): | ||
65 | POST variables and then checked for validity. | 84 | POST variables and then checked for validity. |
66 | """ | 85 | """ |
67 | form = self.get_form() | 86 | form = self.get_form() |
87 | + print(form) | ||
68 | if form.is_valid(): | 88 | if form.is_valid(): |
69 | - | 89 | + print(form) |
70 | self.form_data = form.cleaned_data | 90 | self.form_data = form.cleaned_data |
71 | return self.form_valid(form) | 91 | return self.form_valid(form) |
72 | else: | 92 | else: |
@@ -86,6 +106,8 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | @@ -86,6 +106,8 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | ||
86 | context['init_date'] = params_data['init_date'] | 106 | context['init_date'] = params_data['init_date'] |
87 | context['end_date'] = params_data['end_date'] | 107 | context['end_date'] = params_data['end_date'] |
88 | context['subject'] = subject | 108 | context['subject'] = subject |
109 | + | ||
110 | + | ||
89 | if params_data['from_mural']: | 111 | if params_data['from_mural']: |
90 | context['data'], context['header'] = self.get_mural_data(subject, params_data['init_date'], params_data['end_date']) | 112 | context['data'], context['header'] = self.get_mural_data(subject, params_data['init_date'], params_data['end_date']) |
91 | return context | 113 | return context |
@@ -115,22 +137,22 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | @@ -115,22 +137,22 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | ||
115 | create_date__range=(init_date, end_date)) | 137 | create_date__range=(init_date, end_date)) |
116 | 138 | ||
117 | #number of help posts created by the student | 139 | #number of help posts created by the student |
118 | - interactions['v01'] = help_posts_made_by_user.count() | 140 | + interactions['number of help posts created by the user'] = help_posts_made_by_user.count() |
119 | 141 | ||
120 | help_posts = SubjectPost.objects.filter(action="help", create_date__range=(init_date, end_date), | 142 | help_posts = SubjectPost.objects.filter(action="help", create_date__range=(init_date, end_date), |
121 | space__id=subject.id) | 143 | space__id=subject.id) |
122 | 144 | ||
123 | #comments count on help posts created by the student | 145 | #comments count on help posts created by the student |
124 | - interactions['v02'] = Comment.objects.filter(post__in = help_posts.filter(user=student), | 146 | + interactions['amount of comments on help posts created by the student'] = Comment.objects.filter(post__in = help_posts.filter(user=student), |
125 | create_date__range=(init_date, end_date)).count() | 147 | create_date__range=(init_date, end_date)).count() |
126 | 148 | ||
127 | 149 | ||
128 | #count the amount of comments made by the student on posts made by one of the professors | 150 | #count the amount of comments made by the student on posts made by one of the professors |
129 | - interactions['v03'] = Comment.objects.filter(post__in = help_posts.filter(user__in= subject.professor.all()), create_date__range=(init_date, end_date), | 151 | + interactions['amount of comments made by the student on teachers help posts'] = Comment.objects.filter(post__in = help_posts.filter(user__in= subject.professor.all()), create_date__range=(init_date, end_date), |
130 | user=student).count() | 152 | user=student).count() |
131 | 153 | ||
132 | #comments made by the user on other users posts | 154 | #comments made by the user on other users posts |
133 | - interactions['v04'] = Comment.objects.filter(post__in = help_posts.exclude(user=student), | 155 | + interactions['amount of comments made by the student on other students help posts'] = Comment.objects.filter(post__in = help_posts.exclude(user=student), |
134 | create_date__range=(init_date, end_date), | 156 | create_date__range=(init_date, end_date), |
135 | user= student).count() | 157 | user= student).count() |
136 | 158 | ||
@@ -141,7 +163,7 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | @@ -141,7 +163,7 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | ||
141 | for comment in comments_by_teacher: | 163 | for comment in comments_by_teacher: |
142 | help_posts_ids.append(comment.post.id) | 164 | help_posts_ids.append(comment.post.id) |
143 | #number of help posts created by the user that the teacher commented on | 165 | #number of help posts created by the user that the teacher commented on |
144 | - interactions['v05'] = help_posts.filter(user=student, id__in = help_posts_ids).count() | 166 | + interactions['Number of help posts created by the user that the teacher commented on'] = help_posts.filter(user=student, id__in = help_posts_ids).count() |
145 | 167 | ||
146 | 168 | ||
147 | comments_by_others = Comment.objects.filter(user__in=subject.students.exclude(id = student.id)) | 169 | comments_by_others = Comment.objects.filter(user__in=subject.students.exclude(id = student.id)) |
@@ -149,33 +171,33 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | @@ -149,33 +171,33 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | ||
149 | for comment in comments_by_teacher: | 171 | for comment in comments_by_teacher: |
150 | help_posts_ids.append(comment.post.id) | 172 | help_posts_ids.append(comment.post.id) |
151 | #number of help posts created by the user others students commented on | 173 | #number of help posts created by the user others students commented on |
152 | - interactions['v06'] = help_posts.filter(user=student, id__in = help_posts_ids).count() | 174 | + interactions['number of help posts created by the user others students commented on'] = help_posts.filter(user=student, id__in = help_posts_ids).count() |
153 | 175 | ||
154 | #Number of student visualizations on the mural of the subject | 176 | #Number of student visualizations on the mural of the subject |
155 | - interactions['v07'] = MuralVisualizations.objects.filter(post__in = SubjectPost.objects.filter(space__id=subject.id), | 177 | + interactions['Number of student visualizations on the mural of the subject'] = MuralVisualizations.objects.filter(post__in = SubjectPost.objects.filter(space__id=subject.id), |
156 | user = student).count() | 178 | user = student).count() |
157 | 179 | ||
158 | 180 | ||
159 | #VAR20 - number of access to mural between 6 a.m to 12a.m. | 181 | #VAR20 - number of access to mural between 6 a.m to 12a.m. |
160 | - interactions['v20'] = Log.objects.filter(action="access", resource="subject", | 182 | + interactions[' number of access to mural between 6 a.m to 12a.m.'] = Log.objects.filter(action="access", resource="subject", |
161 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (5, 11)).count() | 183 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (5, 11)).count() |
162 | 184 | ||
163 | - #VAR21 - number of access to mural between 6 a.m to 12a.m. | ||
164 | - interactions['v21'] = Log.objects.filter(action="access", resource="subject", | 185 | + #VAR21 - number of access to mural between 0 p.m to 6p.m. |
186 | + interactions['number of access to mural between 0 p.m to 6p.m.'] = Log.objects.filter(action="access", resource="subject", | ||
165 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (11, 17)).count() | 187 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (11, 17)).count() |
166 | #VAR22 | 188 | #VAR22 |
167 | - interactions['v22'] = Log.objects.filter(action="access", resource="subject", | 189 | + interactions[' number of access to mural between 6 p.m to 12p.m.'] = Log.objects.filter(action="access", resource="subject", |
168 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (17, 23)).count() | 190 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (17, 23)).count() |
169 | 191 | ||
170 | #VAR23 | 192 | #VAR23 |
171 | - interactions['v23'] = Log.objects.filter(action="access", resource="subject", | 193 | + interactions[' number of access to mural between 0 a.m to 6a.m.'] = Log.objects.filter(action="access", resource="subject", |
172 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (23, 5)).count() | 194 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (23, 5)).count() |
173 | 195 | ||
174 | #VAR24 through 30 | 196 | #VAR24 through 30 |
175 | day_numbers = [0, 1, 2, 3, 4, 5, 6] | 197 | day_numbers = [0, 1, 2, 3, 4, 5, 6] |
176 | day_names = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"] | 198 | day_names = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"] |
177 | for day_num in day_numbers: | 199 | for day_num in day_numbers: |
178 | - interactions['v'+ str(24+day_num)] = Log.objects.filter(action="access", resource="subject", | 200 | + interactions['number of access to the subject on '+ day_names[day_num]] = Log.objects.filter(action="access", resource="subject", |
179 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__week_day = day_num).count() | 201 | user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__week_day = day_num).count() |
180 | 202 | ||
181 | for value in interactions.values(): | 203 | for value in interactions.values(): |
@@ -185,3 +207,4 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | @@ -185,3 +207,4 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView): | ||
185 | header.append(key) | 207 | header.append(key) |
186 | return data, header | 208 | return data, header |
187 | 209 | ||
210 | + |