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

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Django: реализовать несколько различных нумераций идентификаторов для внешних ключей.

Сообщение Anonymous »

У меня есть приложение-форум, его структура: «форум -> подфорум -> тема -> комментарии». Темы индивидуальны для каждого подфорума и недоступны из другого подфорума; то же самое для тем и их комментариев.
Из-за плохой организации структуры данных с моей стороны нумерация идентификаторов комментариев повторяется как общая для всех тем, поэтому идентификатор первого комментария первой созданной темы — 1, а идентификатор первого комментария последней созданной темы может быть, я не знаю, 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('/', TopicListView.as_view(), name='subforum'),
path('/add_topic/', AddTopic.as_view(), name="add_topic"),
path('/topics//', ShowTopic.as_view(), name='topic'),
path('/topics//add_comment/', AddComment.as_view(), name="add_comment"),
path('/topics//edit//', UpdateComment.as_view(), name="edit_comment"),
]
models.py:

Код: Выделить всё

from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.text import slugify

from .consts import *

class Subforum(models.Model):
title = models.CharField(verbose_name='Название', max_length=32, choices=Theme.THEME_CHOICES, default=1)
slug = models.SlugField(default='News')
objects = models.Manager()

class Meta:
ordering = ['title']
verbose_name = 'Разделы форума'
verbose_name_plural = 'Разделы форума'

def __str__(self):
return self.title

def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.title)
return super(Subforum, self).save(*args, **kwargs)

def get_absolute_url(self):
return reverse('forum:subforum', kwargs={'subforum_slug': self.slug})

class Topic(models.Model):
subject = models.CharField(verbose_name='Заголовок', max_length=255, unique=True)
first_comment = models.TextField(verbose_name='Сообщение', max_length=2000, default='')
slug = models.SlugField(default='', unique=True, max_length=25, editable=False)
subforum = models.ForeignKey('Subforum',
verbose_name='Раздел',
on_delete=models.CASCADE,
related_name='subforum')
creator = models.ForeignKey(User,
verbose_name='Создатель темы',
on_delete=models.SET('deleted'),
related_name='creator')
created = models.DateTimeField(auto_now_add=True)
closed = models.BooleanField(default=False)
objects = models.Manager()

class Meta:
ordering = ['id']
verbose_name = 'Обсуждения'
verbose_name_plural = 'Обсуждения'

def __str__(self):
return self.subject

def save(self, *args, **kwargs):
if not self.id:
self.slug = f'topic-{slugify(self.subject)}'
return super(Topic, self).save(*args, **kwargs)

def get_absolute_url(self):
return reverse('forum:topic', kwargs={'topic_slug': self.slug, 'subforum_slug':  self.subforum.slug})

class Comment(models.Model):
topic = models.ForeignKey('Topic',
verbose_name='Тема',
on_delete=models.CASCADE,
related_name='comments')
author = models.ForeignKey(User,
verbose_name='Комментатор',
on_delete=models.SET('deleted'),
related_name='author')
content = models.TextField(verbose_name='Текст', max_length=2000)
created = models.DateTimeField(verbose_name='Дата публикации', auto_now_add=True)
updated = models.DateTimeField(verbose_name='Дата изменения', auto_now=True)
objects = models.Manager()

class Meta:
ordering = ['created']
verbose_name = 'Комментарии'
verbose_name_plural = 'Комментарии'

def __str__(self):
return f'Post of {self.topic.subject} is posted by {self.author.username}.'
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']
Если потребуется какая-либо дополнительная информация, готов ее предоставить.

Подробнее здесь: https://stackoverflow.com/questions/791 ... reign-keys
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»