[英]Check for unique constraint inside the save method
I have a model on which the unique_together parameter is not working.我有一个 model,其 unique_together 参数不起作用。 The reason is that most of the times the "client_repr" variable is set on the save() method.
原因是大多数时候“client_repr”变量是在 save() 方法上设置的。 If someone creates a task with the same ('client_repr', 'task_type'... ) combination the model won't detect it because the "client_repr" value is null until the end of the save() method.
如果有人使用相同的 ('client_repr', 'task_type'...) 组合创建任务,model 将不会检测到它,因为在 save() 方法结束之前“client_repr”值为 null。
How can i call for a unique constraint verification inside the save() method?我如何在 save() 方法中调用唯一约束验证?
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)
I know i could just make a search (ex: if Task.objects.get(...): ) but is it the most django-pythonic way?我知道我可以进行搜索(例如:如果 Task.objects.get(...): )但它是最 django-pythonic 的方式吗?
clean()
clean()
It's not directly what you asked, but it's generally more django-friendly and does not require weird things like overriding save()
这不是你直接问的,但它通常对 django 更友好,不需要像覆盖
save()
这样奇怪的东西
class Task(Model):
def clean():
# your code starts here
if not self.b_client:
self.client_repr = str(self.client)
else:
self.client_repr = str(self.b_client)
# your code ends here
Since this custom clean()
is called before django calls validate_unique()
, it should fulfill your requirements.由于此自定义
clean()
在 django 调用validate_unique()
之前被调用,因此它应该满足您的要求。
See the details in the official documentation.请参阅官方文档中的详细信息。
save()
save()
中做所有事情To check unique constraints, you can do the following:要检查唯一约束,您可以执行以下操作:
from django.core.exceptions import ValidationError
def save(self, *args, **kwargs):
... # your code that automatically sets some fields
try:
self.validate_unique()
# self.full_clean() # <- alternatively, can use this to validate **everything**, see my comments below
except ValidationError:
# failed
# that's up to you what to do in this case
# you cannot just re-raise the ValidationError because Django doesn't expect ValidationError happening inside of save()
super().save(*args, **kwargs)
Note:笔记:
self.validate_unique()
does not guarantee, that the updated earlier in save()
values are good and don't violate something elseself.validate_unique()
并不能保证之前更新的save()
值是好的并且不违反其他内容self.full_clean()
is safer, but will be slightly slower (how slow - depends on the validators you have) self.full_clean()
更安全,但会稍微慢一些(有多慢——取决于你拥有的验证器)Django documentation says : Django 文档说:
There are three steps involved in validating a model:
验证 model 涉及三个步骤:
- Validate the model fields - Model.clean_fields()
验证 model 字段 - Model.clean_fields()
- Validate the model as a whole - Model.clean()
整体验证 model - Model.clean()
- Validate the field uniqueness - Model.validate_unique()
验证字段唯一性 - Model.validate_unique()
All three steps are performed when you call a model's full_clean() method.
当您调用模型的 full_clean() 方法时,将执行所有三个步骤。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.