我对如何构建模型有疑问。
我想给一些实体投票的可能性,在这种情况下,是一份文件。我提出了两种可能性:
选项1:
Link the entity as a relationship
class Vote(model.Model):
author = models.ForeignKey(User)
created = models.DateField(auto_now=True)
value = models.IntegerField(default=1)
class Paper(models.Model):
author = models.ForeignKey(User)
edition = models.ForeignKey(ConferenceEdition)
votes = models.OneToMany(Vote)
优点:
- 使用模型(ORM)更容易
- 我可以与其他人一起使用此投票实体
- 在呈现HTML时,我可能需要这些信息,以显示用户已经投票的论文
干燥剂:
- 恐怕数据库越大,速度就越慢
选项2:
不链接类
class Vote(model.Model):
author = models.ForeignKey(User)
created = models.DateField(auto_now=True)
value = models.IntegerField(default=1)
entity_id = models.IntegerField()
entity_type = models.CharField(max_length=255,default='Paper')
class Paper(models.Model):
author = models.ForeignKey(User)
edition = models.ForeignKey(ConferenceEdition)
num_votes = models.IntegerField(default=0)
可用性:
- 这是一种懒惰的加载,我有一个计数器,如果我需要信息,我可以去它
- 它更快(我想)
干燥剂:
- 您必须依靠一个新的逻辑来更新所有新的投票
选项3:
我在听
谢谢!
Django只有在显式调用它们时才会加载多对多字段。
所以在你的第一个案例中:
paper.votes.all()
如果你想在查询时加载所有选票,你可以在django 1.4中进行预取相关
paper = Paper.objects.get(pk=1).prefetch_related('votes')
顺便说一句,您可以使用.count()来代替.all(),后者生成一个不同的数据库查询,速度要快得多,因为它只需要对值进行计数,而不需要将它们检索到django/python中。
还有第三种方法:
你可以在你的模型中有一个额外的字段:votes_count,你可以在pre_save()上更新它,它会为你保存这个值。这样你既可以查询所有选票,也可以只获取一个数字。