from django.contrib.auth import get_user_model from django.db import models from django.db.models import CASCADE from django.urls import reverse User = get_user_model() class StoryRound(models.Model): name = models.CharField(max_length=256) participants = models.ManyToManyField(User) # for ordering add: through='Participant' created = models.DateTimeField(auto_now_add=True) number_of_rounds = models.IntegerField() current_turn = models.IntegerField(default=0, blank=True) def get_absolute_url(self): return reverse('writing:detail', kwargs={'pk': self.pk}) def get_next_story_part(self, user: User) -> 'StoryPart': return StoryPart.objects.get( part_of__part_of_round=self, turn_number=self.current_turn, user=user ) def next_round_ready(self) -> bool: for story in self.story_set.all(): if not story.storypart_set.get(turn_number=self.current_turn).finished: return False return True #class Participant(models.Model): # user = models.ForeignKey(User, on_delete=CASCADE) # story_round = models.ForeignKey(StoryRound, on_delete=CASCADE) # order_by = models.IntegerField() class Story(models.Model): name = models.CharField(max_length=256, null=True, blank=True) created = models.DateTimeField(auto_now_add=True) part_of_round = models.ForeignKey(StoryRound, on_delete=CASCADE) started_by = models.ForeignKey(User, on_delete=CASCADE) finished = models.BooleanField(default=False) def get_first_unfinished_part(self): if self.finished: return None first_part = StoryPart.objects.get(part_of_id=self.pk, previous_part__isnull=True) last_unfinished_part = first_part while last_unfinished_part.finished: last_unfinished_part = StoryPart.objects.get(previous_part=last_unfinished_part) return last_unfinished_part class StoryPart(models.Model): user = models.ForeignKey(User, on_delete=CASCADE) previous_part = models.ForeignKey('StoryPart', on_delete=CASCADE, null=True, blank=True) text = models.TextField(null=True, blank=True) part_of = models.ForeignKey('Story', on_delete=CASCADE) turn_number = models.IntegerField() @property def finished(self): return self.text