django - 如何确保模型仅在另一个已经存在时才创建一个实例
问题描述
在模型中,我需要防止使用相同的标识符代码创建孤立术语(首选术语的同义词或相关术语)。现在我有以下内容:
from django.utils.translation import gettext_lazy as _
from django.db import models
class TopographyCodes(models.Model):
code = models.CharField(
max_length=5,
primary_key=True,
)
class TopographyFourCharactersDescription(models.Model):
code = models.ForeignKey(
'TopographyCodes',
on_delete=models.CASCADE,
)
term = models.CharField(max_length=200)
class TermType(models.IntegerChoices):
PREFERRED = 1, _('Preferred term')
SYNONYM = 2, _('Synonym')
RELATED = 3, _('Related or equivalent')
term_type = models.IntegerField(
max_lenght=1,
choices=TermType.choices,
default=TermType.PREFERRED,
)
def is_preferred(self):
return self.type in {
self.TermType.PREFERRED,
}
class Meta:
constraints = [
# We only support one preferred description per code
models.UniqueConstraint(
fields=['code'],
condition=Q(term_type=1),
name='unique_preferred_code'),
]
现在,如果 is_main 返回 true(或将返回 true),则应该允许创建新术语。我正在使用表单集来编辑此模型,它假定它已创建,但我希望模型保证如果没有具有相同代码但首选的条目,则不存在任何术语。
数据库已经存在这类问题,我想防止它们发生。
解决方案
由于您的模型与自身有关系,请创建它。就像是:
preferred_term = models.ForeignKey(
'self',
null=True,
limit_choices_to={'is_preferred': True},
on_delete=models.CASCADE,
)
现在您可以使用检查约束来验证当 term_type 不等于 1 时,确保 preferred_term 不为 NULL:
class Meta:
constraints = [
[...]
models.CheckConstraint(
check=(Q(preferred_term__isnull=False) & Q(term_type__gt=1)) | Q(term_type=1),
由于此规则不适用于您首选的术语,因此只需在等于 1 时无条件地通过检查。
推荐阅读
- javascript - jQuery:单个变量中的多个选择器
- postgresql - 选择 Heroku Dataclip 上的所有表
- python - 货币转换数据框 - 跳过列
- c# - 如何在 ReactiveUI 中手动重新验证 ValidationContext 的验证?
- html - 拉伸一个元素的高度,但不拉伸另一个元素
- python - 消息:元素点击被拦截:元素...在点 (657, 594) 处不可点击。其他元素会收到 Selenium 的点击
- python - Python Scrapy - 解析最近更新日期的 URL 内容
- r - 在不丢失起始值的情况下逐月计算生存率
- javascript - JavaScript 如何选择主视图
- python - 如何使用动态长度分割字符串?