Django多对多关系的结构化

2 投票
4 回答
509 浏览
提问于 2025-04-16 05:49

我在为学校的年鉴委员会写一个应用程序时,遇到了一些麻烦,特别是在建模一个特定的关系上。目前我有一个照片类

class Photo(models.Model):
 photo = models.ImageField(upload_to="user_photos/")
 name = models.CharField(blank=True, max_length=50)

 rating = models.IntegerField(default=1000)

 wins = models.IntegerField(default=0)
 matches = models.IntegerField(default=0)

和一个用户类

class UserProfile(models.Model):
 user = models.ForeignKey(User, unique=True)
 group = models.CharField(max_length=50)

这两个类都运行得很好。我想做的是把它分开,让每张照片有一个全球评分,这个评分是根据所有用户的投票得出的,同时也有一个仅基于用户对该照片投票的评分。不幸的是,我不知道该怎么结构化这个关系。我的第一个想法是使用一个多对多的字段,但我也在考虑把评分单独放到一个模型里,像这样:

class Rating(models.Model)
     photo = models.ManyToOne(Photo)
     rating = models.IntegerField(default=1500)

这样也许可以。

有没有Django的高手(或者说任何稍微懂点的人,因为我知道我不太行)能给我一些建议,告诉我该如何处理这个简单的问题呢?

4 个回答

0

我不太明白你的问题,不过在Django中,如果你想表示一种多对一的关系,可以使用ForeignKey字段!不过正如Ignacio提到的,使用一个中介模型来表示多对多的关系也可能对你有帮助!

2

你需要一个中介表

1

你想要一个自定义的多对多字段。

class Rating(models.Model):
    photo = models.ForeignKey(Photo)
    user = models.ForeignKey(User)
    rating = models.IntegerField(default=1500)

class Photo(models.Model):
    photo = models.ImageField(upload_to="user_photos/")
    name = models.CharField(blank=True, max_length=50)

    rating = models.ManyToManyField(User, through='Rating')

    wins = models.IntegerField(default=0)
    matches = models.IntegerField(default=0)

这样你就可以通过照片对象或者用户对象来查询数据。

不过,这种方法比较简单,可能不太适合大规模使用。在一个非常受欢迎的网站上,评分模型可能会因为请求太多而变得很拥挤。更专业的网站会通过引入一个冗余的整数字段,比如说 rating_total,来简化这个依赖关系,并设置一个定时任务定期更新这个字段。这样一来,你就不需要通过多对多的关系来构建查询,而是可以直接从这个字段获取结果。

撰写回答