Как автоматически обновить атрибут модели при создании другой модели

Я изучал django и django rest на нескольких различных курсах и начал свой собственный проект, который будет представлять собой веб-приложение типа форума.

У меня 4 модельных класса Category, SubCategory, Thread и Post. Я хочу иметь атрибут для подкатегории под названием num_threads, который может быть обновлен, когда создается тема для подкатегории, с которой она связана. Аналогично я хочу, чтобы у темы были атрибуты num_posts и num_views. Я использовал внешние ключи для связи моделей. Теперь я не уверен, что делаю эту часть правильно. Вот мой model.py:

from django.db import models
from django.contrib.auth.models import User


class Category(models.Model):
    """
    Category Class:
    Main Categories for GRDG Forum
    Creation and Deletion will be restricted to site admin
    """

    # Attributes
    name = models.CharField(max_length=32, unique=True, blank=False)
    description = models.TextField(max_length=150, blank=True)

    def __str__(self):
        return self.name


class SubCategory(models.Model):
    """
    SubCategory Class:
    SubCategories will be one to many relation with category ie: Multiple subcategories related to one category
    Creation and Deletion will be restricted to site admin
    GET methods restriction will vary by subcategory
    """

    # References
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

    # Attributes
    name = models.CharField(max_length=32, unique=True, blank=False)
    description = models.TextField(max_length=150)
    num_threads = models.IntegerField(max_length=None, default=0)

    def __str__(self):
        return self.name


class Thread(models.Model):
    """
    Class Thread
    Threads will be one to many relation to subcategory ie: Multiple threads related to one subcategory
    Creation and Deletion restricted to authorized and authenticated users
    GET methods restriction will vary by parent subcategory.
    """

    # References
    subcategory = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
    user = models.ForeignKey(User, models.CASCADE)

    # Attributes
    title = models.CharField(max_length=32, unique=False, blank=False)
    num_views = models.IntegerField(max_length=None, default=0)
    num_posts = models.IntegerField(max_length=None, default=0)
    locked = models.BooleanField(default=False)
    author = models.CharField(max_length=32, blank=False)

    def __str__(self):
        return self.title


class Post(models.Model):
    """
    Class Posts
    Posts will be one to many relation to Thread ie: Multiple posts related to one Thread
    Creation and Deletion restricted to authorized and authenticated users
    """

    # References
    thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
    user = models.ForeignKey(SubCategory, on_delete=models.CASCADE)

    # Attributes
    body = models.TextField(max_length=500, blank=False)
    author = models.CharField(max_length=32, blank=False)

У меня есть ссылки в классах моделей, которые присваивают внешний ключ. Есть ли способ автоматически обновлять атрибут модели, когда создается другой объект с внешним ключом. IE: Увеличение подкатегории num_thread, когда создается поток с тем же внешним ключом.

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

Пожалуйста, дайте мне знать, что есть другие ресурсы, которые я мог бы использовать.

Пожалуйста, не храните количество Threads (или любой другой агрегат) в модели. Это форма дублирования данных, которая часто является антипаттерном: это означает, что вам нужно будет реализовать обработчики, когда Threads создаются, обновляются (ссылаются на другой SubCategory) или удаляются. Оказывается, что синхронизация этих обработок часто представляет собой сложную проблему, даже если две таблицы хранятся в одной и той же базе данных.

Вы можете удалить поле num_thread и использовать .annotate(…) [Django-doc] и подсчитывать количество связанных Thread при необходимости с помощью:

from django.db.models import Count

SubCategory.objects.annotate(
    num_threads=Count('thread')
)

Объекты SubCategory, происходящие из этого набора запросов, будут иметь дополнительный атрибут .num_threads, содержащий количество связанных Thread объектов.

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