Lokicor
Lokicor

Reputation: 137

Django model field automatically incremented, but not according IDs

I am a beginner with Django and I have been searching around this but not reaching a satisfactory solution.

Let's say I would like to create a Model to identify a given chair of a table located in a given room of a house, and also its height (of the chair). Consider then records like the following:

House Room Table Chair Chair Height (cm)
White House Kitchen 1 1 75
White House Kitchen 2 1 55
White House Kitchen 2 2 65
Buckingham Palace Main State Room 1 1 70
Buckingham Palace Main State Room 1 2 70

The compound primary key should include House, Room, Table and Chair. The model I have created does not allow me to increment the integer value of the Chair, once the House, Room and Table are introduced. Is there a way to do that in the models.py file? I do not want to allow the user to introduce any number for the chair field, but to introduce the corresponding following one according to the house, room and table already introduced (There should not be, for example, a 3rd chair without existing the 1st and the 2nd ones).

I have been searching the AutoField type but it does not seem to be what I want. Has this to be considered in other parts of the development? (User forms...)

Thank you very much in advance.

class ChairLocation(models.Model):
    house = models.CharField()
    room = models.CharField()
    table = IntegerField(validators=[MinValueValidator(1)])
    chair = IntegerField(validators=[MinValueValidator(1)])   #¿?¿?¿?¿?

    class Meta:
        unique_together = (('house', 'room', 'table', 'chair),)

...

Upvotes: 2

Views: 311

Answers (1)

Guillaume
Guillaume

Reputation: 2006

You need to override the save method of you model, then get the highest value of chair and increment it yourself.

from django.db.models import Max

class ChairLocation(models.Model):
    house = models.CharField()
    room = models.CharField()
    table = IntegerField(validators=[MinValueValidator(1)])
    chair = IntegerField(validators=[MinValueValidator(1)])   #¿?¿?¿?¿?

    class Meta:
        unique_together = (('house', 'room', 'table', 'chair'),)

    def save(self, *args, **kwargs):
        max_chair = 0
        try:
            max_chair = ChairLocation.objects.filter(house=self.house, room=self.room, table=self.table).aggregate(Max('chair'))["chair__max"]
        except:
            max_chair = 0
        self.chair = max_chair + 1
        return super(ChairLocation, self).save(*args, **kwargs)

Upvotes: 1

Related Questions