2010-10-20 83 views
2

在为我学校的年鉴委员会编写一份申请时,我对建模一个特定的关系感到死路一条。目前,我有一个照片级构造Django多对多关系

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(或者真的,任何稍微有能力的人,因为我知道我不是)大师指出我正在接近这个简单难题的正确方向吗?

回答

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之类的冗余整数字段来对规则依赖进行规范化处理,并设置一个cron作业来定期更新它,以便您不需要通过多对多关系来构建查询,但直接从场上得到结果。

+0

>这种方法很幼稚,并且不会很好地扩展 我认为这样做很多,但现在用户基数很小,这是用于A/B测试的,所以现在担心这一点可能为时过早。现在我有我的模型的方式现在借用穿透表和ManyToMany,但也有一个globalRating类似于您建议w/cron工作的字段。 在网站上,用户投票选择哪张照片更好,他们的评分是使用调整后的Elo公式进行调整的,但用户希望看到他们的评分与整个用户群的评分相比,因此我的问题 – 2010-10-21 20:20:24

2

你想要一个through table

+0

这正是我所寻找的,不能相信我错过了它的文档。谢谢! – 2010-10-21 06:20:20

0

我完全不明白你的问题,但对于一个represeting很多对一个在Django -relation您使用ForeignKey-field!但是正如伊格纳西奥已经指出的,与中间模型的多对多关系对您也可能是有用的!

0

我不太明白这句话:“照片的全球评分来源于整个用户群的投票数,以及仅基于该照片上的用户投票的评分。”

但是,如果您的意思是您希望为所有用户的费用总和创建一个字段评分,并保存另一个包含用户照片费率的字段,你应该首先做一个想法是值得的,因为对于计算的字段,你可以选择在数据库中物理存储(全局速率)这样的值或根据需要计算它们。你应该根据需要计算的值的频率和需要多少信息来计算它的决定。

请注意,存储计算的值意味着每次您对用户速率进行更改时计算该值。