[英]Validation on CreateView and UpdateView in django always being triggered, even when model doesn't/shouldn't
[英]Django model saves when it shouldn't
我正在嘗試在我的 Django 模型上設置自定義驗證規則。 我有以下代碼:
Entity.py
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.db import models
class Entity(models.Model):
TYPE_CHOICES = [
('asset', 'asset'),
('company', 'company')
]
entity_type = models.CharField(max_length=25, choices=TYPE_CHOICES)
...
class Asset(Entity):
...
class Company(Entity):
...
Security.py
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied, ValidationError
from django.db import models
from .Entity import Entity
class Security(models.Model):
...
entities = models.ManyToManyField(Entity)
def clean(self, *args, **kwargs) -> None:
try:
# Check that object has already been saved
Security.objects.get(name=self.name)
print("All entities:", self.entities.all())
if len([e for e in self.entities.all() if e.entity_type == 'company']) > 1:
raise ValidationError("A security can only be related to one company")
except ObjectDoesNotExist:
pass
return super(Security, self).clean(*args, **kwargs)
def save(self, *args, **kwargs):
try:
self.full_clean()
return super(Security, self).save(*args, **kwargs)
except ValidationError:
raise ValidationError("A security can only be related to one company")
class Bond(Security):
...
class Equity(Security):
...
我正在嘗試做的是防止Security
在其現場entities
持有超過 1 家公司時被保存。 entities
字段是與Entity
的 ManyToMany 關系,因為它可以包含多個Asset
對象但只能包含一個Company
。
這是我的測試文件
class EntityTestCase(TestCase):
def test_multiple_companies_fail(self):
b = Bond.objects.get(name='Bond 1')
c1 = Company.objects.get(name='Company 1')
c2 = Company.objects.get(name='Company 2')
a1 = Asset.objects.get(name='Asset 1')
a2 = Asset.objects.get(name='Asset 2')
b.entities.add(c1)
b.save()
b.entities.add(a1)
b.entities.add(a2)
b.save()
try:
b.entities.add(c2)
b.save()
self.fail("Should not be able to link more than one company to a security")
except ValidationError:
b = Bond.objects.get(name='Bond 1')
# Exception gets caught, but following assert fails with `AssertionError: 2 != 1`.
self.assertEquals(len([e for e in b.entities.all() if e.entity_type == 'company']), 1)
我嘗試使用 Django shell 並且我有相同的行為。 即使我在save
方法中引發異常,記錄也會被保存,這似乎不合邏輯。
有人會知道為什么嗎? 我做錯了什么,如何避免根據條件進行儲蓄?
感謝威廉的評論,我實際上找到了解決方案。
m2m 關系不由save()
管理, add(...)
可以。 那么訣竅是這個function:
@receiver(m2m_changed, sender=Security.entities.through)
def check_unique_company(sender, instance, **kwargs):
if len([e for e in instance.entities.all() if e.entity_type == 'company']) > 1:
raise ValidationError("A security can only be related to one company")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.