我有一个unique_together参数不起作用的模型。原因是大多数时候“client_repr”变量是在保存()方法上设置的。如果有人创建了一个具有相同('client_repr','task_type'...)组合时,模型不会检测到它,因为“client_repr”值在保存()方法结束之前都是null。
如何在保存()方法中调用唯一约束验证?
class Task(models.Model):
client = models.ForeignKey(Client, related_name = 'tasks', on_delete = models.CASCADE)
b_client = models.ForeignKey(BClient, related_name = 'tasks', on_delete = models.CASCADE, null = True, blank = True)
client_repr = models.CharField(max_length = 100, null = True, blank = True)
task_type = models.CharField(max_length = 100)
task_description = models.CharField(max_length = 100)
department = models.ForeignKey(Department, related_name = 'tasks', on_delete = models.CASCADE)
extra_fields = models.ManyToManyField(ExtraField, blank = True)
spot = models.BooleanField(default = False)
class Meta:
unique_together = (('client_repr', 'task_type', 'task_description', 'department'), )
def __str__(self):
return ' | '.join([f'{self.client_repr}', f'{self.task_description}', f'{self.task_type}'])
def save(self, *args, **kwargs):
if not self.b_client:
self.client_repr = str(self.client)
else:
self.client_repr = str(self.b_client)
super().save(*args, **kwargs)
我知道我可以做一个搜索(例如:if Task.objects.get(...):)但这是最django-pythonic的方式吗?
1条答案
按热度按时间qzwqbdag1#
选项一:使用
clean()
这并不是你直接要求的,但它通常更适合django,并且不需要像覆盖
save()
这样奇怪的事情由于这个自定义的
clean()
在**django调用validate_unique()
之前被调用,所以它应该可以满足你的要求。详情请参阅官方文档。
选项二:继续执行
save()
中的所有操作要检查唯一约束,可以执行以下操作:
注意事项:
self.validate_unique()
并不能保证先前在save()
中更新的值是好的,并且不违反其他内容self.full_clean()
更安全,但会稍微慢一点(有多慢-取决于您拥有的验证器)文档
Django documentation说道:
验证模型涉及四个步骤:
所有四个步骤都是在调用模型的full_clean()方法时执行的。