298 lines
8.7 KiB
Python
298 lines
8.7 KiB
Python
from django.shortcuts import render
|
|
from django.urls import reverse_lazy, reverse
|
|
from django.views.generic.base import TemplateView
|
|
from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
|
|
from django.views.generic.detail import DetailView
|
|
from django.views.generic.list import ListView
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.forms.models import inlineformset_factory
|
|
from django import forms
|
|
|
|
from django.db.models import ( Exists, OuterRef,
|
|
Prefetch, Subquery, Count, Sum, Avg, F, Q, Value)
|
|
from django.db.models.functions import Length, Upper
|
|
|
|
from students.models import Student, Thread, Message
|
|
|
|
from .models import (
|
|
Tag,
|
|
Subject,
|
|
Component,
|
|
Score,
|
|
)
|
|
|
|
from .forms import ComponentForm, ComponentUpdateForm
|
|
|
|
|
|
# UPLOAD CSV
|
|
# import pandas as pd
|
|
|
|
# csv_data = pd.read_csv('file.csv', sep=';')
|
|
|
|
# products = [
|
|
# Product(
|
|
# name = csv_data.ix[row]['Name'],
|
|
# description = csv_data.ix[row]['Description'],
|
|
# price = csv_data.ix[row]['price'],
|
|
# )
|
|
# for row in csv_data['ID']
|
|
# ]
|
|
|
|
# Product.objects.bulk_create(products)
|
|
|
|
|
|
# if form.is_valid():
|
|
# csv_file = form.cleaned_data['csv_file']
|
|
|
|
|
|
|
|
class SearchResultsView(ListView):
|
|
model = Component
|
|
template_name = 'gradebook/search_results.html'
|
|
|
|
def get_queryset(self):
|
|
query = self.request.GET.get('q')
|
|
object_list = Component.objects.filter(
|
|
Q(name__icontains=query) | Q(tags__name__icontains=query)
|
|
).prefetch_related(
|
|
Prefetch(
|
|
'score_set',
|
|
queryset=Score.objects.select_related('student')
|
|
),
|
|
'tags'
|
|
).annotate(
|
|
grade_avg_pre=Avg('score__value')
|
|
).order_by('subject')
|
|
return object_list
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
query = self.request.GET.get('q')
|
|
context['student_list'] = Student.objects.filter(
|
|
Q(first_name__icontains=query) | Q(last_name__icontains=query) | Q(student_id__icontains=query)
|
|
)
|
|
context['message_list'] = Message.objects.filter(
|
|
Q(content__icontains=query)
|
|
)
|
|
context['query'] = query
|
|
return context
|
|
|
|
|
|
# SUBJECTS
|
|
class SubjectListView(LoginRequiredMixin, ListView):
|
|
model = Subject
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['tag_list'] = Tag.objects.annotate(Count('component'))
|
|
return context
|
|
|
|
class SubjectCreateView(LoginRequiredMixin, CreateView):
|
|
model = Subject
|
|
template_name_suffix = '_create_form'
|
|
fields = ('__all__')
|
|
|
|
class SubjectDetailView(LoginRequiredMixin, DetailView):
|
|
model = Subject
|
|
|
|
def get_object(self):
|
|
queryset = Subject.objects.filter(
|
|
pk=self.kwargs.get(self.pk_url_kwarg)
|
|
).prefetch_related(
|
|
Prefetch('component_set', queryset=Component.objects.prefetch_related(
|
|
'score_set'
|
|
).annotate(
|
|
grade_avg_pre=Avg('score__value')
|
|
))
|
|
)
|
|
obj = queryset.get()
|
|
return obj
|
|
|
|
|
|
class SubjectUpdateView(LoginRequiredMixin, UpdateView):
|
|
model = Subject
|
|
fields = ('__all__')
|
|
|
|
def get_success_url(self):
|
|
pk = self.kwargs["pk"]
|
|
return reverse('subject-detail', kwargs={'pk': pk})
|
|
|
|
class SubjectDeleteView(LoginRequiredMixin, DeleteView):
|
|
model = Subject
|
|
success_url = reverse_lazy('subject-list')
|
|
|
|
|
|
# COMPONENTS
|
|
class ComponentListView(LoginRequiredMixin, ListView):
|
|
model = Component
|
|
pk_url_kwarg = 'comp_pk'
|
|
|
|
class ComponentCreateView(LoginRequiredMixin, CreateView):
|
|
model = Component
|
|
form_class = ComponentForm
|
|
template_name_suffix = '_create_form'
|
|
pk_url_kwarg = 'comp_pk'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['subject'] = Subject.objects.get(pk=self.kwargs['pk'])
|
|
return context
|
|
|
|
def form_valid(self, form):
|
|
form.instance.subject = Subject.objects.get(pk=self.kwargs['pk'])
|
|
return super().form_valid(form)
|
|
|
|
def get_success_url(self):
|
|
return reverse('component-detail', kwargs={'pk': self.kwargs['pk'], 'comp_pk': self.object.pk})
|
|
|
|
class ComponentDetailView(LoginRequiredMixin, DetailView):
|
|
model = Component
|
|
pk_url_kwarg = 'comp_pk'
|
|
|
|
def get_object(self):
|
|
queryset = Component.objects.filter(
|
|
pk=self.kwargs.get(self.pk_url_kwarg)
|
|
).prefetch_related(
|
|
Prefetch(
|
|
'score_set',
|
|
queryset=Score.objects.select_related('student')
|
|
),
|
|
'tags'
|
|
).annotate(
|
|
grade_avg_pre=Avg('score__value')
|
|
)
|
|
obj = queryset.get()
|
|
return obj
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
cscores = Score.objects.filter(
|
|
component=self.object,
|
|
student=OuterRef('pk')
|
|
)
|
|
context['scoreless'] = Student.objects.exclude(
|
|
score__in=cscores
|
|
)
|
|
return context
|
|
|
|
class ComponentUpdateView(LoginRequiredMixin, UpdateView):
|
|
model = Component
|
|
form_class = ComponentUpdateForm
|
|
pk_url_kwarg = 'comp_pk'
|
|
|
|
def get_success_url(self):
|
|
return reverse('subject-detail', kwargs={'pk': self.object.subject.pk})
|
|
|
|
class ComponentManagerView(LoginRequiredMixin, UpdateView):
|
|
model = Component
|
|
fields = ('finished_grading',)
|
|
pk_url_kwarg = 'comp_pk'
|
|
template_name_suffix = '_manager'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
cscores = Score.objects.filter(
|
|
component=self.object,
|
|
student=OuterRef('pk')
|
|
)
|
|
context['student_list'] = Student.objects.annotate(
|
|
cscore=Subquery(cscores.values('value')),
|
|
cscore_pk=Subquery(cscores.values('pk'))
|
|
)
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
return reverse('component-detail', kwargs={'pk': self.object.subject.pk, 'comp_pk': self.object.pk})
|
|
|
|
def form_valid(self, form):
|
|
form.save()
|
|
for key, value in self.request.POST.items():
|
|
if 'student' in key and value:
|
|
s_pk = key.split('_')[1]
|
|
obj, created = Score.objects.update_or_create(
|
|
component=self.object,
|
|
student=Student.objects.get(pk=s_pk),
|
|
defaults={'value': value}
|
|
)
|
|
return super().form_valid(form)
|
|
|
|
class ComponentDeleteView(LoginRequiredMixin, DeleteView):
|
|
model = Component
|
|
pk_url_kwarg = 'comp_pk'
|
|
|
|
def get_success_url(self):
|
|
return reverse('subject-detail', kwargs={'pk': self.kwargs['pk']})
|
|
|
|
|
|
# SCORES
|
|
class ScoreListView(LoginRequiredMixin, ListView):
|
|
model = Score
|
|
|
|
class ScoreCreateView(LoginRequiredMixin, CreateView):
|
|
model = Score
|
|
template_name_suffix = '_create_form'
|
|
fields = ('__all__')
|
|
|
|
def get_success_url(self):
|
|
return reverse('component-detail', kwargs={'pk': self.object.component.pk})
|
|
|
|
class ScoreDetailView(LoginRequiredMixin, DetailView):
|
|
model = Score
|
|
|
|
class ScoreUpdateView(LoginRequiredMixin, UpdateView):
|
|
model = Score
|
|
fields = ['value']
|
|
|
|
def get_success_url(self):
|
|
return reverse('component-detail', kwargs={'pk': self.object.component.subject.pk, 'comp_pk': self.object.component.pk})
|
|
|
|
class ScoreDeleteView(LoginRequiredMixin, DeleteView):
|
|
model = Score
|
|
|
|
def get_success_url(self):
|
|
return reverse('component-detail', kwargs={'pk': self.object.component.subject.pk, 'comp_pk': self.object.component.pk})
|
|
|
|
|
|
|
|
# TAGS
|
|
class TagListView(LoginRequiredMixin, ListView):
|
|
model = Tag
|
|
|
|
def get_queryset(self):
|
|
object_list = Tag.objects.annotate(Count('component'))
|
|
return object_list
|
|
|
|
class TagCreateView(LoginRequiredMixin, CreateView):
|
|
model = Tag
|
|
template_name_suffix = '_create_form'
|
|
fields = ('__all__')
|
|
|
|
class TagDetailView(LoginRequiredMixin, DetailView):
|
|
model = Tag
|
|
|
|
def get_object(self):
|
|
queryset = Tag.objects.filter(
|
|
pk=self.kwargs.get(self.pk_url_kwarg)
|
|
).prefetch_related(
|
|
Prefetch('component_set', queryset=Component.objects.prefetch_related(
|
|
'score_set'
|
|
).annotate(
|
|
grade_avg_pre=Avg('score__value')
|
|
))
|
|
)
|
|
obj = queryset.get()
|
|
return obj
|
|
|
|
|
|
class TagUpdateView(LoginRequiredMixin, UpdateView):
|
|
model = Tag
|
|
fields = ('__all__')
|
|
|
|
def get_success_url(self):
|
|
pk = self.kwargs["pk"]
|
|
return reverse('tag-detail', kwargs={'pk': pk})
|
|
|
|
class TagDeleteView(LoginRequiredMixin, DeleteView):
|
|
model = Tag
|
|
success_url = reverse_lazy('tag-list')
|