Home > Software design >  Django: Unique IDs for each sub-model of a Model
Django: Unique IDs for each sub-model of a Model

Time:01-09

I'm fairly new to Django, but I believe my question is more towards designing databases regardless of the framework or platform.

Let me explain using following quick pseudo. I have following two models:

class Issue(models.Model):
    title = models.CharField(max_length=60)
    status = models.IntegerField(choices=Status.choices, default=Status.OPEN)
    ...

class Comment(models.Model):
    issue = models.ForeignKey(Issue, on_delete=models.CASCADE, related_name="comments")
    text = models.TextField()
    ...

In my web app, I'm building a collection of Issues. Each issue is assigned a django's auto-generated unique ID number (pk), which is perfect. And for each issue there is a property comments which holds a collection of comments specific to this issue.

Each comment also has a system-generated unique ID, but the sequence of this ID is not specific to the Issue model. Means if I create 3 comments in Issue #1 (comment #1, #2, #3), and then I create a comment under Issue #2, that comment's ID is set as #4 instead of #1.

I understand that this is the way the data models are defined. What I would like to have is that whenever a new issue is created and a comment added, its ID should start from 1. I cannot define comment IDs manually by incrementing over the previous comment ID because the web app will allow users to delete the comments too. So if there are 3 comments under an issue and the last comment #3 is deleted, the next time a comment is added it should be given a unique ID #4.

Any suggestions how do I go about implementing a robust solution to this? TIA

EDIT: The purpose of restarting comment ID from 1 each time is that the comment ID is to be displayed in the HTML against each comment. It will be used by the users for referencing purpose.

CodePudding user response:

It looks to me like you are trying to keep track of the number of comments per issue. This can be done using Issue.comments.count() or use a cached property that is updated every time there is a new comment. If you want to know the order in which the comments were added, you can add a created_at field and use it for ordering in your queries as follows issue.comments.order_by('created_at').

CodePudding user response:

add created_at datetimeField in comment table and sort by created_at to return query

CodePudding user response:

You can make use of forloop.counter

Give this a try

{% for comment in issue.comments.all %}
    No: {{ forloop.counter }}
    {{ comment.text }}
{% endfor %}

Update:

to fix re-numbering on the deletion of a comment, the best thing you can do is to perform a soft-deletion

{% for comment in issue.comments.all %}

    {% if comment.is_active %}
        No: {{ forloop.counter }}
        {{ comment.text }}
     {% endfor %}

{% endfor %}

add an is_active boolean filed to the Comment model

class Comment(models.Model):
    ...
    is_active = models.BooleanField(default=True) 

then instead of deleting the Comment object, set is_active to False, which will prevent renumbering issues in the template

CodePudding user response:

What I would do is probably something a bit different. I would add some kind of hierarchy filed to the Comment model. (and not play around with the Django auto generated id's).

class Comment(models.Model):
    issue = models.ForeignKey(Issue, on_delete=models.CASCADE, related_name="comments")
    text = models.TextField()
    hierarchy = models.IntegerField() 
...

This way the comments by id will look like this:

  1. Issue1 - C1, C2, C3 ... C1-h1, C2-h2, C3-h3 (where h is the hierarchy)
  2. Issue2 - C4, C5, C6 ... C4-h1, C5-h2, C6-h3.

This way you will be able to show on the frontend the hierarchy (not the id), and when you will delete a comment (you mentioned this), you will be able to continue with h4. (by my understanding this was your intended purpose).

Let me know if I should clarify more.

  •  Tags:  
  • Related