Fixed slot rooms by using database more natively
This commit is contained in:
		
							parent
							
								
									38e2124c64
								
							
						
					
					
						commit
						2c954c3a05
					
				
					 3 changed files with 26 additions and 51 deletions
				
			
		|  | @ -1,7 +1,6 @@ | ||||||
| from django.db import models | from django.db import models | ||||||
| 
 | 
 | ||||||
| from symposion.conference.models import Section | from symposion.conference.models import Section | ||||||
| from symposion.schedule.utils import InlineSet |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Schedule(models.Model): | class Schedule(models.Model): | ||||||
|  | @ -39,18 +38,18 @@ class SlotKind(models.Model): | ||||||
| class Slot(models.Model): | class Slot(models.Model): | ||||||
|      |      | ||||||
|     day = models.ForeignKey(Day) |     day = models.ForeignKey(Day) | ||||||
|     room_set = models.TextField(db_column="rooms") |  | ||||||
|     kind = models.ForeignKey(SlotKind) |     kind = models.ForeignKey(SlotKind) | ||||||
|     start = models.TimeField() |     start = models.TimeField() | ||||||
|     end = models.TimeField() |     end = models.TimeField() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class SlotRoom(models.Model): | ||||||
|  |     """ | ||||||
|  |     Links a slot with a room. | ||||||
|  |     """ | ||||||
|      |      | ||||||
|     @property |     slot = models.ForeignKey(Slot) | ||||||
|     def rooms(self): |     room = models.ForeignKey(Room) | ||||||
|         attr = "_rooms" |      | ||||||
|         if not hasattr(self, attr): |     class Meta: | ||||||
|             class RoomInlineSet(InlineSet): |         unique_together = [("slot", "room")] | ||||||
|                 def consecutive_count(self): |  | ||||||
|                     return len(self) |  | ||||||
|             value = RoomInlineSet(obj=self, field="room_set", delimiter=" ") |  | ||||||
|             setattr(self, attr, value) |  | ||||||
|         return getattr(self, attr) |  | ||||||
|  |  | ||||||
|  | @ -1,6 +1,9 @@ | ||||||
| import itertools | import itertools | ||||||
|  | import operator | ||||||
| 
 | 
 | ||||||
| from symposion.schedule.models import Room, Slot | from django.db.models import Count | ||||||
|  | 
 | ||||||
|  | from symposion.schedule.models import Room, Slot, SlotRoom | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TimeTable(object): | class TimeTable(object): | ||||||
|  | @ -9,21 +12,28 @@ class TimeTable(object): | ||||||
|         self.day = day |         self.day = day | ||||||
|      |      | ||||||
|     def slots_qs(self): |     def slots_qs(self): | ||||||
|         return Slot.objects.filter(day=self.day) |         qs = Slot.objects.all() | ||||||
|  |         qs = qs.filter(day=self.day) | ||||||
|  |         return qs | ||||||
|      |      | ||||||
|     def rooms(self): |     def rooms(self): | ||||||
|         return Room.objects.filter(schedule=self.day.schedule).order_by("order") |         qs = Room.objects.all() | ||||||
|  |         qs = qs.filter(schedule=self.day.schedule) | ||||||
|  |         qs = qs.filter(pk__in=SlotRoom.objects.filter(slot__in=self.slots_qs().values("pk")).values("room")) | ||||||
|  |         qs = qs.order_by("order") | ||||||
|  |         return qs | ||||||
|      |      | ||||||
|     def __iter__(self): |     def __iter__(self): | ||||||
|         times = sorted(set(itertools.chain(*self.slots_qs().values_list("start", "end")))) |         times = sorted(set(itertools.chain(*self.slots_qs().values_list("start", "end")))) | ||||||
|         slots = list(self.slots_qs().order_by("start")) |         slots = Slot.objects.filter(pk__in=self.slots_qs().order_by("start", "slotroom__room__order").values("pk")) | ||||||
|  |         slots = slots.annotate(room_count=Count("slotroom")) | ||||||
|         row = [] |         row = [] | ||||||
|         for time, next_time in pairwise(times): |         for time, next_time in pairwise(times): | ||||||
|             row = {"time": time, "slots": []} |             row = {"time": time, "slots": []} | ||||||
|             for slot in slots: |             for slot in slots: | ||||||
|                 if slot.start == time: |                 if slot.start == time: | ||||||
|                     slot.rowspan = TimeTable.rowspan(times, slot.start, slot.end) |                     slot.rowspan = TimeTable.rowspan(times, slot.start, slot.end) | ||||||
|                     slot.colspan = slot.rooms.consecutive_count() |                     slot.colspan = slot.room_count | ||||||
|                     row["slots"].append(slot) |                     row["slots"].append(slot) | ||||||
|             if row["slots"] or next_time is None: |             if row["slots"] or next_time is None: | ||||||
|                 yield row |                 yield row | ||||||
|  |  | ||||||
|  | @ -1,34 +0,0 @@ | ||||||
| class InlineSet(object): |  | ||||||
|      |  | ||||||
|     def __init__(self, obj, field, delimiter): |  | ||||||
|         self.obj = obj |  | ||||||
|         self.field = field |  | ||||||
|         self.data = set([x for x in getattr(obj, field).split(delimiter) if x]) |  | ||||||
|         self.delimiter = delimiter |  | ||||||
|      |  | ||||||
|     def __iter__(self): |  | ||||||
|         return iter(self.queryset()) |  | ||||||
|      |  | ||||||
|     def __len__(self): |  | ||||||
|         return self.queryset().count() |  | ||||||
|      |  | ||||||
|     def queryset(self): |  | ||||||
|         return self.obj.__class__._default_manager.filter(pk__in=self.data) |  | ||||||
|      |  | ||||||
|     def add(self, obj, commit=True): |  | ||||||
|         """ |  | ||||||
|         Add given room to the set, but check if it can exist |  | ||||||
|         before adding it. |  | ||||||
|         """ |  | ||||||
|         self.data.add(obj.pk) |  | ||||||
|         self._update_model(commit=commit) |  | ||||||
|      |  | ||||||
|     def remove(self, obj, commit=True): |  | ||||||
|         self.data.remove(obj.pk) |  | ||||||
|         self._update_model(commit=commit) |  | ||||||
|      |  | ||||||
|     def _update_model(self, commit=True): |  | ||||||
|         value = self.delimiter.join([str(x) for x in self.data]) |  | ||||||
|         setattr(self.obj, self.field, value) |  | ||||||
|         if commit: |  | ||||||
|             self.obj.save(force_update=True) |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue