在 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',' 上的唯一性时,它将强制 SomeData.name 和 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)
希望对你有帮助!
关于python - 改变继承的 Django 模型的独特字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45687127/