python - django ValidationError 未在测试中引发但在 shell 中引发
问题描述
我在下面定义了一个模型,它在 clean() 方法中调用管理器。
from django.core.exceptions import ValidationError
from django.db import models
from re import sub
class Vessel(models.Model):
name = models.CharField(max_length=50)
stripped_name = models.CharField(
max_length=50, unique=True, null=True, blank=True
)
def save(self, *args, **kwargs):
stripped_name = sub(r'\s+', ' ', str(self.name).upper().strip())
stripped_name = sub(r'^M[^a-zA-Z]*V\s*', '', stripped_name)
stripped_name = sub(r'[^\w]', '', str(stripped_name).upper())
self.stripped_name = stripped_name
super().save(*args, **kwargs)
def clean(self):
stripped_name = sub(r'\s+', ' ', str(self.name).upper().strip())
stripped_name = sub(r'^M[^a-zA-Z]*V\s*', '', stripped_name)
stripped_name = sub(r'[^\w]', '', str(stripped_name).upper())
if Vessel.objects.all().filter(stripped_name = stripped_name).exists():
return ValidationError("Vessel name exists.")
在新刷新的 shell 中,IntegrityError 被很好地提升。
>>> from my_random_app.models import Vessel
>>> vessel = Vessel(name='PM Hayabusa')
>>> vessel.save()
>>> vessel = Vessel(name=' M/V PM-HAYABUSA')
>>> vessel.save() # Raises IntegrityError
甚至 ValidationError 也被很好地提出。
>>> from my_random_app.models import Vessel
>>> vessel = Vessel(name='PM Hayabusa')
>>> vessel.save()
>>> vessel = Vessel(name=' M/V PM-HAYABUSA')
>>> vessel.clean() # Raises ValidationError
但在自动化测试中,不会引发 ValidationError。
from django.core.exceptions import ValidationError
from django.db.utils import IntegrityError
from django.test import TestCase
from my_random_app.models import Vessel
class VesselTest(TestCase):
def setUp(self):
pass
def test_a(self):
vessel = Vessel(name='PM Hayabusa')
vessel.save()
vessel = Vessel(name=' M/V PM-HAYABUSA')
self.assertRaises(IntegrityError, vessel.save)
def test_b(self):
vessel = Vessel(name='PM Hayabusa')
vessel.save()
vessel = Vessel(name=' M/V PM-HAYABUSA')
# This line FAILS!
self.assertRaises(ValidationError, vessel.clean)
这与我在 clean() 方法中调用管理器的方式有关吗?为什么在 shell 中出现验证错误,但在测试中没有出现?
解决方案
你所做的几乎是完美的:)
ValidationError 是一个异常,需要引发一些事情,而不是打算返回。
如果您更换return
->raise
您的问题将得到解决。
if Vessel.objects.all().filter(stripped_name = stripped_name).exists():
raise ValidationError("Vessel name exists.")
当您在 shell clean 方法中执行此操作时,会返回错误,因此您认为它可以正常工作,但实际上并非如此。
>>> from my_random_app.models import Vessel
>>> vessel = Vessel(name='PM Hayabusa')
>>> vessel.save()
>>> vessel = Vessel(name=' M/V PM-HAYABUSA')
>>> vessel.clean() # Returns ValidationError
ValidationError(['Vessel name exists.'])
当它升起时,它变成了流动的:
>>> from my_random_app.models import Vessel
>>> vessel = Vessel(name='PM Hayabusa')
>>> vessel.save()
>>> vessel = Vessel(name=' M/V PM-HAYABUSA')
>>> vessel.clean()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/***/**/myapp/models.py", line 25, in clean
raise ValidationError("Vessel name exists.")
django.core.exceptions.ValidationError: ['Vessel name exists.']
推荐阅读
- android - 将依赖项移动到 Android 中的外部库
- android - 如何处理模型类中的 NULL SAFETY?
- javascript - 掷骰子检查数字是否在 1 到 6 之间
- kubernetes - 在运行时从另一个 pod 动态生成 pod
- c++ - C++ 设计问题:嵌套类(结构)和“父”引用
- docker-compose - 如何使用 podman-compose 启用容器间通信
- react-native - 如何显示来自 AsyncStorage 变量的数据
- sql-server - 用户“sa”登录失败。原因:服务器处于单用户模式。目前只有一位管理员可以连接
- cocoa - Xamarin.Mac 项目中新窗口中的 Xamarin.Forms
- php - 从本地主机替换 WordPress 主题而不会丢失生产站点数据