在 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 但我想知道这是否可以以更透明的方式完成.即,动态修改/创建此 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...
我的自定义模型管理器将过滤数据(为每个唯一 ID 获取最大版本号)以便: SomeData.objects.all() 会回来的
id | name 1 | bobby 2 | nicky 3 | momo
并且还将提供其他可以返回数据的方法,如版本 n-1 中那样。
显然,我将使用时间戳而不是版本号,以便我可以在给定日期检索数据,但原理保持不变。
现在的问题是当我这样做的时候 ./manage.py makemigrations 对于上述模型,当我需要的是 ('SomeData.id',' version_number') 和 ('SomeData.name', 'version_number')。明确地说,我需要将基本模型中的一些字段附加到在数据库中声明为唯一的继承模型的字段中,这在任何时候 manage.py 命令运行和/或生产服务器运行时都是如此.
请您参考如下方法:
通过“动态修改/创建此 unique_together 字段”,我假设您的意思是您想在代码级别而非数据库级别强制执行此操作。
您可以在模型的 save() 方法中执行此操作:
from django.core.exceptions import ValidationError
def save(self, *args, **kwargs):
if SomeData.objects.filter(name=self.name, version_number=self.version_number).exclude(pk=self.pk).exists():
raise ValidationError('Such thing exists')
return super(SomeData, self).save(*args, **kwargs)
希望对您有所帮助!
