【问题标题】:Instance will be created even when required chart field doesn't set explicit即使所需图表字段未明确设置,也会创建实例
【发布时间】:2020-01-07 07:54:37
【问题描述】:

我创建了几个模型,例如组织。我在测试中注意到的问题是,即使short_description 为空,我也可以在模型上使用create 方法,它会保存一个新实例。

我确实设置了验证器它没有帮助

class Organization(models.Model):
    # auto creates with signals pre_save
    code = models.CharField(
        primary_key=True,
        max_length=255,
        blank=False,
        null=False,
        help_text='Unique code or id that can be used to identify organization'
    )
    name = models.CharField(
        max_length=255,
        blank=False,
        null=False,
        help_text='Short name of the organization'
    )
    short_description = models.CharField(
        max_length=255,
        blank=False,
        null=False,
        help_text='Brief overview of the organization',
        validators=[MinLengthValidator(1)]
    )

测试

# this will pass
@pytest.mark.django_db
def test_organization_create():
    obj = Organization.objects.create(name='TEST')
    assert obj.code

期望的行为是我创建的 Organization 实例,如果我不指定 short_description 将引发错误。

【问题讨论】:

  • 你的意思是“short_description”?

标签: django


【解决方案1】:

我在测试中注意到的问题是我可以在模型上使用 create 方法,即使 short_description 为空,它也会保存一个新实例。

这是正确。出于性能原因,Django 的 ORM 调用将忽略验证器。

您可以使用.full_clean() method [Django-doc] 验证您的对象:

@pytest.mark.django_db
def test_organization_create():
    obj = Organization(name='TEST')
    obj.full_clean()  # will raise an error
    obj.save()
    assert obj.code

一个 Django ModelForm [Django-doc] 将进行完全清理,因此通过表单输入数据将产生有效的对象(对于您添加到表单的字段有效)。这是您应该使用 Django 的表单来处理用户对模型对象的输入的众多原因之一。

【讨论】:

  • 没有验证器和full_clean还有其他方法吗?如果我明确设置blank=False, null=False,我不明白为什么要执行其他操作。我希望这是强制性的和需要的。无论我用Organization(...).save()Organization.objects.create() 创建什么?我已经设置该字段不能为空和空白
  • @ArtemDumanov:其中一些属性,如null=False 被转换为数据库级别,但所有自定义验证器本质上只是可调用的并且可以是任何东西,因此这些无法转换为数据库.您可以在save() 方法中添加full_clean(..) 调用,但例如,这不适用于Organization.objects.update(short_description='')。所以一般来说你无法解决这个问题。
  • 如果我要使用DRF,请问如何处理这个问题?我应该验证什么、在哪里以及如何验证?
  • @ArtemDumanov; DRF 不使用full_clean,而是通过在序列化程序级别定义的验证器进行验证:stackoverflow.com/q/32834026/67579
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多