亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

檢查保存方法內的唯一約束

檢查保存方法內的唯一約束

桃花長相依 2023-10-18 15:32:54
我有一個模型, unique_together 參數不起作用。原因是大多數時候“client_repr”變量是在 save() 方法上設置的。如果有人使用相同的 ('client_repr', 'task_type'...) 組合創建任務,模型將不會檢測到它,因為在 save() 方法結束之前“client_repr”值為 null。如何在 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)我知道我可以進行搜索(例如: if Task.objects.get(...): ),但這是最 django-pythonic 的方式嗎?
查看完整描述

1 回答

?
米脂

TA貢獻1836條經驗 獲得超3個贊

選項 1:使用clean()

這不是你直接要求的,但它通常對 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

由于此自定義clean()是在django 調用之前validate_unique()調用的,因此它應該滿足您的要求。


選項 2:繼續執行中的所有操作save()

要檢查唯一約束,您可以執行以下操作:


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)

筆記:


只做并self.validate_unique()不能保證早期更新的save()值是好的并且不會違反其他內容

self.full_clean()更安全,但會稍微慢一些(多慢 - 取決于您擁有的驗證器)

文檔

Django文檔說:

驗證模型涉及四個步驟:

  • 驗證模型字段 - Model.clean_fields()

  • 驗證整個模型 - Model.clean()

  • 驗證字段唯一性 - Model.validate_unique()

  • 驗證約束 - Model.validate_constraints()

當您調用模型的full_clean()方法時,將執行所有四個步驟。


查看完整回答
反對 回復 2023-10-18
  • 1 回答
  • 0 關注
  • 121 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號