Django: реализуйте несколько различных чисел id для внешних ключей

У меня есть приложение для форума, его структура - «форум -> подфорум -> тема -> комментарии». Темы являются специальными для каждого подфорума и недоступны из другого подфорума; то же самое касается тем и комментариев к ним.

Из-за плохой организации структуры данных с моей стороны, id комментариев итерируется как общий для всех тем, поэтому id первого комментария первой созданной темы равен 1, а id первого комментария последней созданной темы может быть, я не знаю, 45.

Мне нужно адресовать комментарии внутри тем по их id (или какому-то другому типу нумерации), а для этого нужна какая-то очевидная нумерация системы комментариев внутри тем. Правда, я не знаю, как это реализовать и возможно ли это вообще.

Поэтому я прошу помощи у сообщества.

Файлы: forum/urls.py:

from django.urls import path

from forum.views import *


app_name = 'forum'

urlpatterns = [
    path('', SubForumListView.as_view(), name='forum'),
    path('<slug:subforum_slug>/', TopicListView.as_view(), name='subforum'),
    path('<slug:subforum_slug>/add_topic/', AddTopic.as_view(), name="add_topic"),
    path('<slug:subforum_slug>/topics/<slug:topic_slug>/', ShowTopic.as_view(), name='topic'),
    path('<slug:subforum_slug>/topics/<slug:topic_slug>/add_comment/', AddComment.as_view(), name="add_comment"),
    path('<slug:subforum_slug>/topics/<slug:topic_slug>/edit/<int:id>/', UpdateComment.as_view(), name="edit_comment"),
]

models.py:

views.py:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy, reverse
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django_filters.views import FilterView

from core.views import menu
from .filters import TopicFilter
from .forms import AddTopicForm, AddCommentForm
from .models import Subforum, Topic, Comment, Profile
from .utils import DataMixin


class SubForumListView(ListView):
    model = Subforum
    context_object_name = 'subforum_list'
    template_name = "forum/forum.html"

    def get_context_data(self, **kwargs):
        subforums = Subforum.objects.all()
        context = {'subforums': subforums}
        return context


class TopicListView(FilterView):
    model = Topic
    template_name = "forum/subforum.html"
    slug_url_kwarg = 'subforum_slug'
    context_object_name = 'topics'
    filterset_class = TopicFilter

    def get_queryset(self):
        qs = self.model.objects.all()
        if self.kwargs.get('subforum_slug'):
            qs = qs.filter(subforum__slug=self.kwargs['subforum_slug'])
        return qs


class ShowTopic(DetailView):
    model = Topic
    template_name = "forum/topic.html"
    slug_url_kwarg = 'topic_slug'
    context_object_name = 'topic'

    def get_context_data(self, **kwargs):
        topic = get_object_or_404(Topic, slug=self.kwargs['topic_slug'])
        comments = Comment.objects.filter(topic=topic)
        comments_number = len(Comment.objects.filter(topic__id=topic.id))
        context = {'menu': menu,
                   'topic': topic,
                   'comments': comments,
                   'comm_num': comments_number}
        return context


class AddTopic(DataMixin, CreateView):
    form_class = AddTopicForm
    template_name = 'forum/addtopic.html'
    page_title = 'Create a new topic'
    success_url = reverse_lazy('topic')


class AddComment(LoginRequiredMixin, DataMixin, CreateView):
    model = Comment
    form_class = AddCommentForm
    template_name = 'forum/addcomment.html'
    page_title = 'Leave a comment'

    def get_success_url(self):
        return reverse('forum:topic', kwargs={
            'subforum_slug': self.kwargs['subforum_slug'],
            'topic_slug': self.kwargs['topic_slug']})

    def form_valid(self, form):
        topic = Topic.objects.get(slug=self.kwargs['topic_slug'])
        form.instance.author = self.request.user
        form.instance.topic = topic
        return super(AddComment, self).form_valid(form)


class UpdateComment(LoginRequiredMixin, DataMixin, UpdateView):
    model = Comment
    form_class = AddCommentForm
    template_name = 'forum/addcomment.html'
    page_title = 'Edit comment'

    def get_success_url(self):
        return reverse('forum:topic', kwargs={
            'subforum_slug': self.kwargs['subforum_slug'],
            'topic_slug': self.kwargs['topic_slug']})

forms.py:

from django import forms
from django.core.exceptions import ValidationError

from forum import models


class AddTopicForm(forms.ModelForm):
    subject = forms.CharField(label="Заголовок", max_length=100, min_length=7)
    first_comment = forms.CharField(label="Сообщение", widget=forms.Textarea())

    class Meta:
        model = models.Topic
        fields = ['subject', 'first_comment']

    def clean_subject(self):
        subject = self.cleaned_data['subject']
        if len(subject) > 100:
            raise ValidationError("Length is longer than 100 symbols")
        if len(subject) < 7:
            raise ValidationError("Too short, no less than 7 symbols")
        return subject


class AddCommentForm(forms.ModelForm):
    content = forms.CharField(label="Comment's text", max_length=2000, min_length=1, widget=forms.Textarea())

    class Meta:
        model = models.Comment
        fields = ['content']

Если потребуется какая-либо дополнительная информация, я готов ее предоставить.

Вернуться на верх