As a toy problem for learning Django, I am trying to create a simple web app that tracks encounters and initiative for one of my D&D campaigns. I have a database with models for combatants:
class Combatant(models.Model):
name = models.CharField(max_length=64)
dex_modifier = models.IntegerField(default=0)
initiative = models.IntegerField(null=True)
status = models.CharField(max_length=64, default='healthy')
surprised = models.BooleanField(default=False)
...
and encounters:
class Encounter(models.Model):
combatants = models.ManyToManyField(Combatant)
queue: deque[Combatant]
status = models.CharField(max_length=16, default='inactive')
...
Note that deque in the Encounter model. It becomes important later.
So far I have been able to populate the Combatant and Encounter databases and render a static page listing all Combatants in a given Encounter in descending order of initiative and dex_modifier. What I would like to do is add a button that "rotates" the view, moving the first Combatant in the list from the top to the bottom without altering the underlying data. I thought I could accomplish that using Python's collections.deque like so
class Encounter(models.Model):
...
def Begin(self):
self.status = 'active'
self.queue = deque(self.combatants.all().order_by('-initiative', '-dex_modifier'))
while self.queue[0].surprised:
self.queue[0].surprised = False
self.queue.rotate(-1)
self.save()
def Advance(self):
if self.status == 'inactive':
self.Begin()
else:
self.queue.rotate(-1)
while self.queue[0].surprised:
self.queue[0].surprised = False
self.queue.rotate(-1)
In retrospect that was a pretty braindead move, because there's no way for Encounter.queue to persist between queries. My next thought was to move the deque to the corresponding view, maybe converting the view from a function to a class with a __call__ member function and a static data member for the deque. But, I suspect that I am already making things more complicated than they need to be, probably because I've been dialed in all day and am finally starting to crash.
Anyway, my questions:
- Is it possible to achieve the functionality I want using only Django and html tempaltes, or do I have to resort to, e.g., JavaScript and do some live page rendering?
- Whether that's possible or not, what are the alternatives?
queue[counter % len(queue)]. However, this approach will have difficulties if the length of the queue changes.