4

我试图在 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一个复合主键,然后在和inRating上创建一个唯一约束。不幸的是,Django 不支持复合键。我考虑过覆盖 的方法,但如果可能的话,我更愿意在数据库级别设置约束。systemfilmFilmRatingssave()FilmRating

任何人都知道如何做到这一点?如果有帮助的话,重组表格也可以。

4

3 回答 3

2

我认为你应该看看validate_unique

几年前在stackoverflow中同样的问题

Django 文档

于 2012-11-07T19:13:04.337 回答
2

编辑:根据@JoshSmeaton 和@MSaavedra 的评论更新答案

使用 Django 的syncdb hook,您可以ALTER TABLE直接在数据库上运行语句。如果违反了唯一约束, Django 将引发一个IntegrityError,即使该约束不是由 django 定义的。

然后,添加约束validate_unique将减少开发人员的困惑,并在 Django 中安全地执行约束。

于 2012-11-08T03:03:26.350 回答
1

您可以使用模型字段验证。

https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects

于 2012-11-07T19:23:44.663 回答