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 symposion.conference.models import Section | ||||
| from symposion.schedule.utils import InlineSet | ||||
| 
 | ||||
| 
 | ||||
| class Schedule(models.Model): | ||||
|  | @ -39,18 +38,18 @@ class SlotKind(models.Model): | |||
| class Slot(models.Model): | ||||
|      | ||||
|     day = models.ForeignKey(Day) | ||||
|     room_set = models.TextField(db_column="rooms") | ||||
|     kind = models.ForeignKey(SlotKind) | ||||
|     start = models.TimeField() | ||||
|     end = models.TimeField() | ||||
| 
 | ||||
| 
 | ||||
| class SlotRoom(models.Model): | ||||
|     """ | ||||
|     Links a slot with a room. | ||||
|     """ | ||||
|      | ||||
|     @property | ||||
|     def rooms(self): | ||||
|         attr = "_rooms" | ||||
|         if not hasattr(self, attr): | ||||
|             class RoomInlineSet(InlineSet): | ||||
|                 def consecutive_count(self): | ||||
|                     return len(self) | ||||
|             value = RoomInlineSet(obj=self, field="room_set", delimiter=" ") | ||||
|             setattr(self, attr, value) | ||||
|         return getattr(self, attr) | ||||
|     slot = models.ForeignKey(Slot) | ||||
|     room = models.ForeignKey(Room) | ||||
|      | ||||
|     class Meta: | ||||
|         unique_together = [("slot", "room")] | ||||
|  |  | |||
|  | @ -1,6 +1,9 @@ | |||
| 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): | ||||
|  | @ -9,21 +12,28 @@ class TimeTable(object): | |||
|         self.day = day | ||||
|      | ||||
|     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): | ||||
|         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): | ||||
|         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 = [] | ||||
|         for time, next_time in pairwise(times): | ||||
|             row = {"time": time, "slots": []} | ||||
|             for slot in slots: | ||||
|                 if slot.start == time: | ||||
|                     slot.rowspan = TimeTable.rowspan(times, slot.start, slot.end) | ||||
|                     slot.colspan = slot.rooms.consecutive_count() | ||||
|                     slot.colspan = slot.room_count | ||||
|                     row["slots"].append(slot) | ||||
|             if row["slots"] or next_time is None: | ||||
|                 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