23

私は現在、Django でサイトをコーディングしています (あまりにも多くのフレームワークを学ぶことは決してできないためです!)、関連するオブジェクトに関してオブジェクトを自動インクリメントする方法があるかどうか疑問に思っています。たとえば、Entry モデルと EntryVersion モデルがあるとします。

エントリー
- タイトル
- スラッグ

EntryVersion
- エントリ (外部キー)
- version_number
- コンテンツ

version_numberエントリの外部キーに関して自動インクリメントしたい(エントリに複数のバージョンがあり、1 つから始まり、1 つ上に移動するようにするため)。ただし、データベース内で一意ではないため、真の自動インクリメントにはなりません (version_number = 1 のエントリ バージョンが多数存在する可能性があります。特定のエントリには 1 つだけです)。

私は自分の管理者をロールバックしてそこでこれを処理できることを知っていますが、新しいエントリ バージョンが保存されるたびに、Django 管理者がバージョン番号を自動的に 1 ずつ増やす方法があるかどうか疑問に思っていました。


編集:私が使用した特定のコード(最初の保存時にのみバージョン番号を設定するように修正されました)

Tiago の答えは正しかったのですが、同様のジレンマを持つ将来の StackOverflow ユーザーのために、私が使用した特定のコードを次に示します。

def save(self, force_insert=False, force_update=False):
    # Only modify number if creating for the first time (is default 0)
    if self.version_number == 0:
        # Grab the highest current index (if it exists)
        try:
            recent = EntryVersion.objects.filter(entry__exact=self.entry).order_by('-version_number')[0]
            self.version_number = recent.version_number + 1
        except IndexError:
            self.version_number = 1
    # Call the "real" save() method
    super(EntryVersion, self).save(force_insert, force_update)

インデックス付きのorder_byトリックは、Django のドキュメント (こちら) から収集したものです。

http://docs.djangoproject.com/en/dev/topics/db/queries/#id4

これが機能するには、フィールドでdefault=0定義しておく必要があることに注意してください。version_number

もっと良い方法があるかもしれませんが、これはまさに私が必要としていた方法で機能しているようです。うまくいけば、他の人もそれが役立つと思うでしょう。

4

1 に答える 1