Djangoでは、他のモデルのデータの異なるバージョンを透過的に追跡するために使用できるベースモデルを作成しようとしています。ような何か:継承されたDjangoモデルのユニークなフィールドを変更する
class Warehouse(models.Model):
version_number = models.IntegerField()
objects = CustomModelManagerFilteringOnVersionNumber()
class Meta:
abstract=True
def save(self, *args, **kwargs):
# handling here version number incrementation
# never overwrite data but create separate records,
# don't delete but mark as deleted, etc.
pass
class SomeData(Warehouse):
id = models.IntegerField(primary_key=True)
name = models.CharField(unique=True)
私が持っている問題はSomeData.name
が実際に一意ではないということです、タプル('version_number', 'name')
です。
SomeData
にMeta
クラスを使用できることはわかっていますが、これはもっと透明な方法で行うことができるかどうか疑問に思っていました。つまり、このunique_together
フィールドを動的に変更/作成します。
最終的なメモ:モデルの継承でこれを処理するのは正しいアプローチではないかもしれませんが、このフィールドの一意性の問題を処理できるなら、かなり魅力的でした。
編集:明らかに、この文脈では「動的」という語は誤解を招くものである。私は、一意性がデータベースレベルで保持されることを願っています。アイデアは異なるバージョンのデータを持つことです。データベースが含まれている可能性が
:
version_number | id | name | #comment 0 | 1 | bob | first insert 0 | 2 | nicky | first insert 1 | 1 | bobby | bob changed is name on day x.y.z 0 | 3 | malcom| first insert 1 | 3 | malco | name change 2 | 3 | momo | again...
と私のカスタムを
Aは、ここでは上記のモデル(すべてが同じテーブルにあるように、抽象モデルの継承を前提とする)との小さな例を与えますようにモデルマネージャは、(すべての一意のIDのバージョン番号に最大を取って)データをフィルタします: SomeData.objects.all() は
id | name 1 | bobby 2 | nicky 3 | momoを返します
と同様に、バージョンn-1のようにデータを返すことのできるメソッドを提供します。
明らかに、バージョン番号の代わりにタイムスタンプを使用して、特定の日付にデータを取得できるようにしますが、原則は同じです。
今の問題は、私は ./manage.py makemigrations上記のモデルと を行うとき、私は必要なのに一意であるとき、それはSomeData.name上とSomeData.idに一意性を強制するということです( 'SomeData.id'、 'version_number')と( 'SomeData.name'、 'version_number')。明示的に、ベースモデルのいくつかのフィールドを、db内でユニークであると宣言された継承モデルのフィールドに追加する必要があります。manage.pyコマンドが実行され、実稼働サーバーが実行されます。
私はそれを何度か読んでも問題は発生する可能性がありますが、コード例を追加できますか? –
モデルの各フィールドにこのunique_togetherフィルタが必要ですか?これはdbレベルで強制されることに注意してください。 –
私は質問をより明確に編集しました。ありがとう –