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)

コメントが示すように、各映画は複数の評価を持つことができますが、評価システムごとに1つの評価しかありません。たとえば、映画はMPAAによって「R」と「PG」の両方を評価することはできません。ただし、MPAAでは「R」、BBFCでは「15」と評価できます。

Djangoでこの制約を形式化するのに苦労しています。やりたいこと:

unique_together = ('film', 'rating__system')

しかし、FilmRatingそのような関係に従うことは許可されていないようです。純粋なSQLを使用している場合は、で複合主キーを作成codeしてから、、で一意の制約を作成します。残念ながら、Djangoは複合キーをサポートしていません。のメソッドをオーバーライドすることを検討しましたが、可能であればデータベースレベルで制約を設定したいと思います。systemRatingsystemfilmFilmRatingssave()FilmRating

誰かがこれを行う方法を知っていますか?それが助けになるなら、テーブルの再構築もうまくいくでしょう。

4

3 に答える 3

2

編集: @ JoshSmeatonと@MSaavedraのコメントに基づいて回答を更新

Django のsyncdb hookALTER TABLEを使用すると、ステートメントをデータベースで直接実行できます。その制約が Django によって定義されていなくても、 Django はIntegrityError一意の制約に違反した場合に例外を発生させます。

次に、制約を追加すると、validate_unique後で開発者の混乱が軽減され、Django で制約が安全に適用されます。

于 2012-11-08T03:03:26.350 に答える
2

見てみるといいと思いますvalidate_unique

数年前のスタックオーバーフローでのこの同じ問題

ジャンゴのドキュメント

于 2012-11-07T19:13:04.337 に答える
1

モデルフィールド検証を使用できます。

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

于 2012-11-07T19:23:44.663 に答える