Django: подкласс, отдельный класс или полностью отдельный класс

Я создаю приложение для форума на Django в качестве учебного проекта.

Я не знаю, как подойти к созданию Post объектов. Я хочу, чтобы пользователи могли размещать threads (т.е. новую тему), я хочу, чтобы пользователи могли размещать ответы в этих темах, а также отвечать на другие ответы.

Я хочу включить такие функции, как реакция на сообщения и ответы.

Я был бы признателен за отзывы о различных подходах, которые я рассматриваю:

Моя мысль заключается в том, что, поскольку два типа постов настолько похожи, они должны наследовать общие поля/методы от родительского класса. Я не уверен, как Django представит это в БД. Изначально это был абстрактный класс

class Post(models.Model):
    post_body = models.TextField(max_length=2000)
    publish_date = models.DateTimeField("date posted")
    author = models.ForeignKey(User, on_delete=models.CASCADE)

class ThreadPost(Post):
    post_title = models.Charfield(200)
    is_solved = models.BooleanField("is_issue_solved", default=False)

class ReplyPost(Post):
    is_solution = models.BooleanField("is_this_the_solution", default=False)
    thread_post = models.ForeignKey(ThreadPost, on_delete=models.CASCADE)

Позже я начал использовать это, основываясь на ответе stackoverflow. Однако я нахожу его немного неудобным в работе, так как мне часто приходится фильтровать сообщения по тому, является ли оно темой или ответом, и искать тему, в которую отвечает сообщение. В этом случае просто иметь отдельные классы кажется более эффективным. Мне действительно нужно лучше разбираться в запросах и т. д.

class Post(models.Model):
    post_title = models.CharField(max_length=200, blank=True, null=True)  
    post_body = models.TextField(max_length=2000)
    publish_date = models.DateTimeField("date posted", auto_now_add=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    parent_post = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='replies')
    is_solved = models.BooleanField("is_issue_solved", default=False)
    is_solution = models.BooleanField("is_this_the_solution", default=False)

    def __str__(self):
        return self.post_title or self.post_body[:30]

    @property
    def is_thread(self):
        return self.parent_post is None

    @property
    def is_reply(self):
        return self.parent_post is not None


class Reaction(models.Model):
    REACTION_CHOICES = [
        ('thumbs_up', 'Thumbs Up'),
        ('thumbs_down', 'Thumbs Down'),
        ('laugh', 'Laugh'),
        # ...
    ]
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    reaction_type = models.CharField(max_length=20, choices=REACTION_CHOICES)

    def __str__(self):
        return f"{self.user.username} - {self.reaction_type}"

class Report(models.Model):
    REPORT_CHOICES = [
        ('spam', 'Spam'),
        ('abusive', 'Abusive Content'),
        # ...
    ]
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    reason = models.CharField(max_length=20, choices=REPORT_CHOICES)
    report_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.user.username} reported {self.post.id} for {self.reason}"

Наконец, я мог бы просто иметь отдельные несвязанные классы Thread и Reply. Я полагаю, что проблема с этим заключается в повторении кода и в том, как другие классы будут взаимодействовать с ними. Например, класс Reaction должен будет учитывать два несвязанных типа Post.

class ThreadPost(modesl.Model):
    Title = models.Charfield(200)
    body = models.TextField(max_length=2000)
    publish_date = models.DateTimeField("date posted")
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    is_solved = models.BooleanField("is_issue_solved", default=False)

class ReplyPost(models.Model):
    body = models.TextField(max_length=2000)
    publish_date = models.DateTimeField("date posted")
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    threadpost = models.ForeignKey(ThreadPost, on_delete=models.CASCADE)
    is_solution = models.BooleanField("is_this_the_solution", default=False)

Может ли ответ также быть потоком (как в ответе на ответ, также возможно)? Если ДА, то вы должны иметь следующий способ реализации этого.

#FB: Feedback along

class ThreadPost(models.Model):
    title = models.Charfield(200)  # FB: use fields name in smaller case.
    body = models.TextField(max_length=2000)
    publish_date = models.DateTimeField("date posted")
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    is_solved = models.BooleanField("is_issue_solved", default=False)
    is_solution = models.BooleanField("is_this_the_solution", default=False)
    parent = models.ForeignKey(
        "self",
        on_delete=models.CASCADE,
        related_name="child_replies",
        null=True,
        blank=True,
    )
    is_parent = models.BooleanField(default=False)  # if it a Main Thread
Вернуться на верх