Object's unique sequencial index for each user - Django models

I have a table for users and another for what I call ‘documents’ in my database (I use postgresql). That last one has a ‘user/author’ column as a foreign key. How can I set a sequential index column for each user/author? Here’s what’s on my mind:

  • user1 fills the table with 10 rows, then that column varies from 1 up to 10.

  • user2 fills the same table with 5 more items. For those user2’s rows that same column varies from 1 up to 5.

  • If any row of a user gets deleted, that column (for that user’s data) gets “re-indexed”, i.e., if user2 deletes the 3rd entry, the former 4th gets re-indexed to 3, and the former 5th to 4.

How I came up with this problem?

  1. I want to use that column as an index in the url’s model-view. I could use a uuid key instead, but I find, for example, myapp.com/edit/1,myapp.com/edit/2 and so on more organized.

  2. Currently I perform the above described actions at view level: every time a row gets deleted all rows for that user gets re-indexed; every time a new row gets added, it’s index is set. The problem is that I feel that this shouldn’t be the role of a view.

So, what I want is to set a sequential index (positive integer) column unique only for each user/author at model’s level. Meaning: is there’s a field in Django models that can perform that action? Is there’s a similar alternative?

Here’s a very simple idea of the described parts of my app:

# apps/accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import PermissionsMixin

from django.db import models

class CustomUser:
    email = models.EmailField(unique=True, null=False, blanck=True)

# apps/documents/models.py
from django.db import models
from accounts.models import CustomUser

class Document(models.Model):
    author = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    subject = models.CharField(max_length=64)
    content = models.TextField()
    that_index_I_described = models.IntegerField(default=0)

# apps/documents/views.py
from django.views.generic import CreateView
from django.views.generic import ListView
from django.views.generic import DeleteView

from django.urls import reverse_lazy

def reindex_documents(author):
    # access, count rows, reindex if needed
    return number_of_rows_for_author

class CreateDocuemnt(CreateView):
    # login and passes mixins, validations and stuffs
    exam.that_index_I_described = reindex_documents(self.author) + 1
    exam.save()

class ViewDocuments(ListView):
    # login and passes mixins
    # queryset = all user's documents

class DeleteDocument(DeleteView):
    # login and passes mixins
    def get_url_success(self,):
        reindex_documents(self.author)
        return reverse_lazy('list-view')

No, there isn’t. Nor, is it strictly necessary that there be one. (In other words, 99+% of the time there is a different approach.

You mention the situation where an entry is deleted. That’s only one case. Do you also need to handle situations where the entries may be reordered, or if one can get inserted into the list?

You also mention interest in the URLs being “organized”. I would suggest that it’s actually much worse to worry about resequencing those entries than not. What you think may “look organized” may appear to be arbitrary unnecessary changes to someone else.

For example, renumbering the entries is going to change the URL - so if someone was looking at “/edit/3” yesterday, and #2 gets deleted, it’s now different data when they go back to #3, potentially confusing to the user.

In any event, there’s virtually no need to approach this by directly managing index values within the table.

1 Like

I would suggest that it’s actually much worse to worry about resequencing those entries than not. What you think may “look organized” may appear to be arbitrary unnecessary changes to someone else.

Thank you for your suggestion. This helps a lot.

For example, renumbering the entries is going to change the URL - so if someone was looking at “/edit/3” yesterday, and #2 gets deleted, it’s now different data when they go back to #3, potentially confusing to the user.

Yeah, I didn’t think of that. I’ll probably use a uuid in the url instead.

I’ve posted this very question in stackoverflow a while ago, and no answer so far. Here’s the link in case you’re interested in answering there too.

No thank you. I choose not to waste my time with SO. (My opinions about that site are well-documented here and elsewhere.)

1 Like

Thanks. Good to know