【问题标题】:How can you create a non-empty CharField in Django?如何在 Django 中创建一个非空的 CharField?
【发布时间】:2011-08-04 11:21:42
【问题描述】:

我有一个简单的模型,如下所示:

class Group(models.Model):
    name = models.CharField(max_length = 100, blank=False)

我希望这会引发完整性错误,但它不会:

group = Group() # name is an empty string here
group.save()

如何确保 name 变量设置为非空值?即让数据库拒绝任何保存空字符串的尝试?

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    另一个不需要您手动调用clean 的选项是使用这个:

    name = models.CharField(max_length=100, blank=False, default=None)
    
    • blank 将阻止在管理员中提供空字符串或使用表单或序列化程序(大多数情况下)。但是,正如 cmets 中所指出的,不幸的是,这并不能阻止 model.name = "" 之类的事情(手动设置空白字符串)
    • default=None 将在使用 group = Group() 之类的名称时将 name 设置为 None,从而在调用 save 时引发异常

    【讨论】:

    • “空白将防止在您的模型中提供空字符串”。这是错误的。它只防止在管理员或任何使用适当形式或序列化程序的地方传递空字符串。它不会阻止Model.objects.create(name="")model.name = ""; model.save()
    • 你是绝对正确的。我会更新我的答案
    • 不传递任何空字符串的最佳方法是什么?
    • 空白默认设置为 False。无需重新设置..甚至不会反映在迁移中..docs.djangoproject.com/en/4.0/ref/models/fields
    • 当然,但是在这种情况下,我更喜欢明确设置它,因为它是非常有意的 blank=False, default=None 在我的脑海中一起出现。个人喜好
    【解决方案2】:

    或者您可以简单地使用 MinLengthValidator 至少 1 个字符:

    from django.core.validators import MinLengthValidator
    
    class Company(BaseModel):
        """Company"""
    
        name = models.CharField(max_length=255,
                                validators=[MinLengthValidator(1)])
    

    【讨论】:

    • 感谢您优雅的解决方案,它对我帮助很大!
    • 你能用validators=[bool]吗? bool(value) 会为任何错误返回 false,所以空字符串、None 等。虽然如果零数字、空列表等有效则不起作用。
    • 当您使用 instance.save() 或 model.create() 保存模型时,这将不起作用。仅在使用 ModelForm 时有效。检查docs.djangoproject.com/en/dev/ref/validators/…
    【解决方案3】:

    在这种情况下,从Django docs 开始,您的name 将存储为空字符串,因为null 字段选项默认为False。如果要定义自定义默认值,请使用 default 字段选项。

    name = models.CharField(max_length=100, blank=False, default='somevalue')
    

    在此页面上,您可以看到blank 与数据库无关。

    更新:

    您应该覆盖模型的 clean 函数,以进行自定义验证,因此您的模型定义将是:

    class Group(models.Model):
      name = models.CharField(max_length=100, blank=False)
      def clean(self):
        from django.core.exceptions import ValidationError
        if self.name == '':
            raise ValidationError('Empty error message')
    

    或者您可以将ValidationError 替换为其他内容。然后在你打电话给group.save()之前打电话给group.full_clean(),这会打电话给clean()

    其他验证相关的东西是here

    【讨论】:

    • 我明白你的意思。我真正想要的是拒绝任何非空字符串..
    • 我明白了,所以你想验证模型。我认为你应该在group.save() 之前使用 group.full_clean()。但我从未使用过它。 :)
    • 避免需要确保调用full_clean() 的一种方法是使用Charfield(default=None)。这将引发IntegrityError 而不是ValidationError
    • @DanH DanH 的评论应该是这个问题的真正答案。谢谢。
    【解决方案4】:

    我花了很长时间寻找这个简单(和老)问题的最佳解决方案,而从 Django 2.2 开始,实际上有一个非常简单的答案,所以我会在这里写下来以防有人遇到同样的问题问题:

    从 Django 2.2 开始,我们可以定义CheckConstraints,所以很容易定义一个非空字符串约束:

    from django.db import models
    
    class Article(models.Model):
       title = models.CharField(max_length=32)
    
        class Meta:
            constraints = [
                models.CheckConstraint(check=~models.Q(title=""), name="non_empty_title")
            ]
    

    【讨论】:

      【解决方案5】:

      Django 的验证系统假定所有字段都是必需的,除非您提到可以将其留空..

      您是否在 Admin 中注册了课程?当你把它留空时它会显示错误吗??

      【讨论】:

      • 我没有使用管理界面,但看起来空白=真只在那里有效。我希望系统拒绝任何地方的空白字段..
      猜你喜欢
      • 1970-01-01
      • 2015-01-04
      • 1970-01-01
      • 2014-07-14
      • 2016-01-12
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      • 2011-10-30
      相关资源
      最近更新 更多