performed some stupid ass shit nested many to many count to fix broken ass numbers
This commit is contained in:
parent
4710dbe7ce
commit
bd9fe4e735
|
@ -1,11 +1,12 @@
|
|||
from datetime import date, datetime, timedelta
|
||||
from pprint import pprint
|
||||
|
||||
from pytz import timezone
|
||||
|
||||
import aiohttp
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import F, Q, Count, QuerySet
|
||||
from django.db.models import F, Q, Count, QuerySet, Subquery, OuterRef, Sum
|
||||
from django.contrib.auth.models import User
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -144,25 +145,35 @@ class Term(models.Model):
|
|||
.select_related("slot", "slot__term")
|
||||
.prefetch_related("swap_set")
|
||||
.filter(slot__term=self)
|
||||
.annotate(adt_plus=Count("swap", filter=Q(swap__enroll=1)))
|
||||
.annotate(adt_minus=Count("swap", filter=Q(swap__enroll=0)))
|
||||
.annotate(volume=F("slot__capacity") + F("adt_plus") - F("adt_minus")))
|
||||
.annotate(base_vol=Count("groups__members"))
|
||||
.annotate(swap_plus=Count("swap", filter=Q(swap__enroll=1), distinct=True))
|
||||
.annotate(swap_minus=Count("swap", filter=Q(swap__enroll=0), distinct=True))
|
||||
.annotate(volume=F("base_vol") + F("swap_plus") - F("swap_minus")))
|
||||
|
||||
def query_colles_of_student(self, student) -> QuerySet:
|
||||
has_student = ((Q(groups__student=student)
|
||||
& ~Q(swap__enroll=0, swap__student=student))
|
||||
| Q(swap__enroll=1, swap__student=student))
|
||||
|
||||
return (Colle.objects
|
||||
.select_related("slot", "slot__term")
|
||||
.prefetch_related("swap_set")
|
||||
.filter(slot__term=self)
|
||||
.filter((Q(groups__student=student)
|
||||
& ~Q(swap__enroll=0, swap__student=student))
|
||||
| Q(swap__enroll=1, swap__student=student))
|
||||
.annotate(adt_plus=Count("swap", filter=Q(swap__enroll=1)))
|
||||
.annotate(adt_minus=Count("swap", filter=Q(swap__enroll=0)))
|
||||
.annotate(volume=F("slot__capacity") + F("adt_plus") - F("adt_minus")))
|
||||
.annotate(base_vol=Count("groups__members", distinct=True))
|
||||
.annotate(swap_plus=Count("pk", filter=Q(swap__enroll=1), distinct=True))
|
||||
.annotate(swap_minus=Count("pk", filter=Q(swap__enroll=0), distinct=True))
|
||||
.annotate(volume=F("base_vol") + F("swap_plus") - F("swap_minus"))
|
||||
.filter(has_student)
|
||||
)
|
||||
|
||||
def query_colles_not_full_excluding_student(self, student) -> QuerySet:
|
||||
has_student = ((Q(groups__student=student)
|
||||
& ~Q(swap__enroll=0, swap__student=student))
|
||||
| Q(swap__enroll=1, swap__student=student))
|
||||
|
||||
def query_colles_not_full(self) -> QuerySet:
|
||||
return (self.query_colles()
|
||||
.filter(volume__lt=F("slot__capacity"), date__gte=date.today()))
|
||||
.filter(volume__lt=F("slot__capacity"), date__gte=date.today())
|
||||
.exclude(has_student))
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.description
|
||||
|
@ -295,7 +306,7 @@ class Colle(models.Model):
|
|||
"slot__time"]
|
||||
|
||||
slot = models.ForeignKey(Slot, on_delete=models.CASCADE)
|
||||
groups = models.ManyToManyField(Group)
|
||||
groups = models.ManyToManyField(Group, blank=True)
|
||||
date = models.DateField()
|
||||
|
||||
def initial_group(self):
|
||||
|
@ -319,23 +330,22 @@ class Colle(models.Model):
|
|||
def is_attendee(self, student):
|
||||
return self.final_group().contains(student)
|
||||
|
||||
|
||||
def volume(self):
|
||||
def get_volume(self):
|
||||
"""
|
||||
Renvoie le nombre d'étudiants inscrits à la colle en tenant compte des swaps.
|
||||
"""
|
||||
n_base = sum(group.members.count() for group in self.groups.all())
|
||||
n_plus = len(Swap.objects.filter(enroll=True, colle=self))
|
||||
n_moins = len(Swap.objects.filter(enroll=False, colle=self))
|
||||
|
||||
return n_base + n_plus - n_moins
|
||||
return (Student.objects
|
||||
.filter(Q(groups__colle=self)
|
||||
& ~Q(swap__colle=self, swap__enroll=False)
|
||||
| Q(swap__colle=self, swap__enroll=True))
|
||||
.distinct()
|
||||
.count())
|
||||
|
||||
def is_full(self):
|
||||
"""
|
||||
Renvoie si la colle est pleine.
|
||||
"""
|
||||
eff = self.volume()
|
||||
return eff >= self.slot.capacity
|
||||
return self.get_volume() >= self.slot.capacity
|
||||
|
||||
def is_edited(self):
|
||||
"""
|
||||
|
@ -369,7 +379,7 @@ class Colle(models.Model):
|
|||
# func()
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.slot} le {self.date} avec groupes {'+'.join(str(groupe) for groupe in self.groups.all())}"
|
||||
return f"Colle {self.slot.subject} ({self.slot.colleur}); {self.date} {self.slot.time} {self.slot.room}. Groupe(s) {{{'; '.join(str(groupe) for groupe in self.groups.all())}}}"
|
||||
|
||||
def datetime(self):
|
||||
return datetime.combine(self.date, self.slot.time, tzinfo=timezone("Europe/Paris"))
|
||||
|
@ -425,3 +435,13 @@ class CalendarLink(models.Model):
|
|||
fields=['student', 'term'], name='unique_student_term_combination'
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
|
||||
def test():
|
||||
valentin = Student.objects.get(pk=25)
|
||||
term = Term.objects.get(pk=3)
|
||||
colles = term.query_colles_of_student(valentin).order_by("-volume")
|
||||
|
||||
for c in colles:
|
||||
print(f"* {c.slot} {c.volume} : {c.base_vol} + {c.swap_plus} - {c.swap_minus}")
|
|
@ -131,7 +131,7 @@ def marketplace(request):
|
|||
return HttpResponse("pas encore supporté")
|
||||
|
||||
term = student.cls.current_term()
|
||||
colles = term.query_colles_not_full()
|
||||
colles = term.query_colles_not_full_excluding_student(student)
|
||||
|
||||
context = {
|
||||
"colles": colles,
|
||||
|
|
Loading…
Reference in New Issue