Commit 8d82a1f92eb096559f1932c248ad4501b57c6607

Authored by fbormann
1 parent 5456f053

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
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/static/reports/js/report.js 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +
  2 +//Function to get all resources of all topics related to that subjct
  3 +$(function (){
  4 +
  5 +});
0 \ No newline at end of file 6 \ 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">&times;</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">&times;</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 +