1

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:

  1. 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?
  2. Whether that's possible or not, what are the alternatives?
1
  • Instead of rotating a queue, you may be able to use a simple counter that you increment after each action. The current combatant is queue[counter % len(queue)]. However, this approach will have difficulties if the length of the queue changes. Commented Jun 15, 2024 at 3:54

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.