我正试图在Django中代表一些电影收视率数据。以下是我的模型的简化版本,用于说明我的问题:
class RatingSystem(models.Model):
"""This denotes a rating authority and territory in which they operate"""
name = models.CharField(max_length=16)
territory = models.CharField(max_length=32)
class Rating(models.Model):
"""This represents a rating designation used by a rating system."""
code = models.CharField(max_length=16)
description = models.TextField()
system = models.ForeignKey(RatingSystem)
class FilmRating(models.Model):
"""This is a rating for a film and the reason why it received the rating.
Each film can have many ratings, but only one per rating system.
"""
rating = models.ForeignKey(Rating)
film = models.ForeignKey('Film')
reason = models.TextField()
class Film(models.Model):
"""Data for a film."""
title = models.CharField(max_length=64)
synopsis = models.TextField()
ratings = models.ManyToManyField(Rating, through=FilmRating)
正如评论所示,每部电影可以有多个评级,但每个评级系统只有一个评级。例如,MPAA不能将电影评为“R”和“PG”。但是,它可以被MPAA评为'R',BBFC评为'15'。
我正在努力在Django中形式化这个约束。我想这样做:
unique_together = ('film', 'rating__system')
FilmRating
中的但似乎不允许遵循这样的关系。如果我使用纯SQL,我会在code
中将system
和Rating
作为复合主键,然后在system
和film
上设置唯一约束在FilmRatings
。不幸的是,Django不支持复合键。我已经考虑覆盖save()
的{{1}}方法,但如果可能的话,我宁愿在数据库级别使用约束。
任何人都知道如何做到这一点?如果有帮助的话,重组表也没关系。
答案 0 :(得分:2)
答案 1 :(得分:2)
编辑:根据@ JoshSmeaton和@ MSaavedra的评论更新答案
使用Django的syncdb hook,您可以直接在数据库上运行ALTER TABLE
语句。如果违反了唯一约束,Django将引发IntegrityError
,即使django没有定义该约束。
然后,将约束添加到validate_unique
将减少开发人员后来的混淆,并在Django中安全地执行约束。
答案 2 :(得分:1)