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']
Если потребуется какая-либо дополнительная информация, я готов ее предоставить.