【问题标题】:Database Modeling with multiple many-to-many relations in DjangoDjango中具有多个多对多关系的数据库建模
【发布时间】:2023-03-23 18:14:01
【问题描述】:

我可能需要一些帮助来设计我的模型及其关系。

简要概述

  • 书籍:书名(例如“指环王”)
  • 标签:与书籍相关的标签(例如“幻想”、“巫师”、“史诗战斗”)
  • 方面:与标签相关的方面,或者换句话说,当特定标签出现时用户可以评价的方面,例如:
    • 标签“幻想”方面可以是“世界细节”和“时间”
    • 标签“史诗战斗”方面可以是“戈尔水平”和“战斗张力”

每个标签都可以在书的多个实例中使用(例如“指环王”和“Discworld”都有标签“幻想”)

每个方面都可以在标签的多个实例中使用(例如“幻想”和“科幻”都具有“世界细节”方面)

这是一张描述性图片:

(哇,这些都大了)

“为什么你需要那个额外的表 BookAspect?”你可能会问?

因为我想存储与特定图书相关的每个方面的用户评分。

这是这里的主要问题。我想在 Django 中对此进行建模,这就是我目前所得到的:

class Book(models.Model):
    title = models.CharField(max_length=100, unique=True)
    tags = ManyToManyField(Tag)
    # the following line is a workaround...
    aspects = models.ManyToManyField(Aspect, through='BookAspect')

class Tag(models.Model):
    name = models.CharField(max_length=100)
    aspects = models.ManyToManyField(Aspect)

class Aspect(models.Model):
    name = models.CharField(max_length=100)

# this class is a workaround ...
class BookAspect(models.Model):
    book = models.ForeignKey(Book)
    aspect = models.ForeignKey(Aspect)
    # this is from django-ratings
    rating = RatingField(range=5, can_change_vote=True, allow_delete=True, blank=True)

    class Meta:
        unique_together = ('book', 'aspect',)

除了模型之外,我还为action="post_add" 创建了一个m2m_changed 信号监听器:

@receiver(m2m_changed, sender=Book.tags.through)
def m2m_changed_book(sender, instance, action, reverse, pk_set, **kwargs):
    if action is not 'post_add' or reverse:
        return

    # iterate through all newly created tags to manually add
    # the aspects from each tag to the BookAspect table
    for tag_id in pk_set:
        aspects = Tag.objects.get(pk=tag_id).aspects.all()
        # this is annoying, i have to manually set the relations...
        for aspect in aspects:
            bookAspect = BookAspect(book=instance, aspect=aspect)
            bookAspect.save()

虽然这应该可行,但我需要额外的逻辑来处理删除的标签。

但真正令人讨厌的是我必须手动添加每本书的方面关系,以便我可以存储用户评分。当然,我需要对不同书籍的同一方面进行不同的评分。

问题

1。这是正确的方法吗?是我遗漏了什么还是没有我想的那么复杂?

2。是否可以“自动化” Book-Aspect 关系,这样我就不必手动更新关系?

3。如何在 Django 中建模?

【问题讨论】:

    标签: python django django-models many-to-many django-signals


    【解决方案1】:
    • 我认为可以更简单地完成。
    • 我认为,在某种程度上。
    • 我会改变:

      class Book(models.Model):
        title = models.CharField(max_length=100, unique=True)
        tags = ManyToManyField(Tag)
      

    由于aspects 字段在Book 类中无关。

    我不知道你为什么写BookAspect。关于用户评分,您可以:

    class BookRating(models.Model):
      book = models.ForeignKey(Book)
      aspect = models.ForeignKey(Aspect)
      rating = models.RatingField()
      # Method to rate a book and check the aspect belong to one of the book's tags
      def rate(book, aspect):
        # check the aspect is related to a tag which is also related to the book
        # if so, save a new rating entry
      # You can also override the save() method to check the aspect is valid for the book
    

    【讨论】:

    • 这很有希望。但仍然存在我必须手动管理 BookRating 的内容而不是自动获取关联的问题,因为它们已经在其他地方定义了
    猜你喜欢
    • 2018-06-09
    • 2019-02-09
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多