from itertools import groupby from django.core.files.base import ContentFile from django.db import models, IntegrityError from django_softdelete.models import SoftDeleteModel, SoftDeleteManager class ItemManager(SoftDeleteManager): def create(self, **kwargs): container = kwargs.pop('container') if 'uid_deprecated' in kwargs: raise ValueError('uid_deprecated must not be set manually') uid_deprecated = Item.all_objects.filter(event=kwargs['event']).count() + 1 kwargs['uid_deprecated'] = uid_deprecated item = super().create(**kwargs) item.container = container return item def get_queryset(self): return super().get_queryset().filter(returned_at__isnull=True) class Item(SoftDeleteModel): id = models.AutoField(primary_key=True) uid_deprecated = models.IntegerField() description = models.TextField() event = models.ForeignKey('Event', models.CASCADE) returned_at = models.DateTimeField(blank=True, null=True) created_at = models.DateTimeField(null=True, auto_now_add=True) updated_at = models.DateTimeField(blank=True, null=True) @property def container(self): try: return self.container_history.order_by('-timestamp').first().container except AttributeError: return None @container.setter def container(self, value): if self.container == value: return self.container_history.create(container=value) objects = ItemManager() all_objects = models.Manager() class Meta: unique_together = (('uid_deprecated', 'event'),) permissions = [ ('match_item', 'Can match item') ] def __str__(self): return '[' + str(self.id) + ']' + self.description class Container(SoftDeleteModel): id = models.AutoField(primary_key=True) name = models.CharField(max_length=255) created_at = models.DateTimeField(blank=True, null=True) updated_at = models.DateTimeField(blank=True, null=True) @property def items(self): try: history = self.item_history.order_by('-timestamp').all() return [v for k, v in groupby(history, key=lambda item: item.item.id)] except AttributeError: return [] def __str__(self): return '[' + str(self.id) + ']' + self.name class ItemPlacement(models.Model): id = models.AutoField(primary_key=True) item = models.ForeignKey('Item', models.CASCADE, related_name='container_history') container = models.ForeignKey('Container', models.CASCADE, related_name='item_history') timestamp = models.DateTimeField(auto_now_add=True) class Event(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=255) slug = models.CharField(max_length=255, unique=True) start = models.DateTimeField(blank=True, null=True) end = models.DateTimeField(blank=True, null=True) pre_start = models.DateTimeField(blank=True, null=True) post_end = models.DateTimeField(blank=True, null=True) created_at = models.DateTimeField(null=True, auto_now_add=True) updated_at = models.DateTimeField(blank=True, null=True) def __str__(self): return '[' + str(self.slug) + ']' + self.name class Meta: db_table = 'common_event'