X-MUK-625
X-MUK-625

Reputation: 63

how to renumber id when the row deleted in django

I would like to set a limit of the number of rows in certain models. to implement this, when I add a new row to the database in django, I would like to delete the old row and renumber id(pk).

By referring to the following links about the above issue, I was able to set the number of lines limit and delete old lines.

Limit the number of rows in a Django table

However, this solution, when the old row deleted, id(pk) is also deleted. if I set limit number of rows is 100, the row id after deletion database is starting at 101. To solve this issue, I would like to renumber id as starting 1 when deleting old id. Could you tell me how to implement it?

class History(models.Model):
    history = models.IntegerField(default=0)

    def save(self):
        objects = History.objects.all()
        print(id)
        if objects.count() > 100:
           objects[0].delete()

        self.save()


class Player(models.Model):
    user = models.CharField(max_length=255)
    game_count = models.IntegerField(default=0)
    medal = models.IntegerField(default=100, verbose_name='medal')
    game_history = models.ForeignKey(History, on_delete=models.CASCADE,    
    verbose_name='game_history', null=True)

    def __str__(self):
        return self.user

Upvotes: 1

Views: 4005

Answers (1)

Thomas Jiang
Thomas Jiang

Reputation: 1323

First, it might be useful to read the answer to a related thread.

If you really want to do so I guess you can create your own primary key field and set it yourself each time.

from django.db import transaction
from django.db.models import F, Max

class History(models.Model):
    id = models.PositiveIntegerField(primary_key=True)       
    history = models.IntegerField(default=0)

    def save(self):
        with transaction.atomic():
            count = History.objects.count()

            objects = History.objects.all()
            if count > 100:
                objects[0].delete()
                if count > 1:
                    objects.update(id=F('id') - 1)

            if not self.id and count > 0:
                objects = objects.refresh_from_db()  # Update QuerySet
                self.id = objects.annotate(max_count=Max('id')).max_count + 1
            elif not self.id and count == 0:
                self.id = 1

            self.save()

Though I really do think that it's not really the way to go because you wouldn't be making use of the DB's integrity mechanisms, and saving one instance would at least require a couple of calls to the DB, though we could wrap it up in an atomic transaction. So I think a good question to ask yourself is whether it is truly necessary to reset the ID back to 1?

Upvotes: 2

Related Questions