确保字段在Django中始终为null [英] Making sure a field is always null in Django

查看:76
本文介绍了确保字段在Django中始终为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父类,将通过3个不同的模型进行扩展。可以说,父类有一个名为 foo 的字段,并且对于子类之一,该字段必须始终为null。我该如何确保?现在,我正在使用 null = True editable = False 约束。但是,如果在创建对象的过程中暴露了该字段,则可以从外壳程序或API中规避这些问题。

I have a parent class which is being extended by 3 different models. The parent class has a field called foo lets say, and this field needs to be always null for one of the sub-classes. How can I ensure this? Right now, I am using null=True, and editable=False constraints. However, these can be circumvented from the shell or an API if the field is exposed during object creation.

class ThirdSubclass(ParentClass):
    # Over-ridden field from abstract parent class
    foo = models.PositiveSmallIntegerField(blank=True, null=True, editable=False)

我还使用了PositiveSmallIntegerField,因为我想为该字段分配尽可能少的空间。无论如何,我该怎么做?覆盖保存方法是唯一的选择吗?理想情况下,我会喜欢字段定义中的某些内容。谢谢!

I am also using the PositiveSmallIntegerField since I want to allocate as little space as possible for this field. Anyway, how do I do this? Is over-riding the save method the only option? Ideally, I would love something within the field definition. Thanks!

推荐答案

正确的方法取决于您期望模型的使用方式。以下是四种可能的方法,以提高健壮性的顺序:

The right way to do this depends on how you expect your models to be used. Here are four possible approaches, in order of increasing robustness:


  1. 如果所有写入都将通过默认模型形式进行:

  1. If all writes will come through default model forms:

您可以设置默认值:

class ThirdSubclass(ParentClass):
    foo = models.PositiveSmallIntegerField(blank=True, null=True, default=None, editable=False)


  • 如果所有写入都将通过使用模型验证来完成(即调用 full_clean() save()):

    您可以使用验证器:

    def validate_none(value):
        if value is not None:
            raise ValidationError("...")
    
    class ThirdSubclass(ParentClass):
        foo = models.PositiveSmallIntegerField(blank=True, null=True, default=None, editable=False,
                                               validators=[validate_none])
    


  • 如果所有写入都会通过该模型:

  • If all writes will come through the model:

    您可以覆盖 save()

    class ThirdSubclass(ParentClass):
        def save(self, *args, **kwargs):
            if self.foo is not None:
                raise ValueError("...")
            super().save(*args, **kwargs)
    


  • 如果写入可以来自任何地方(例如,使用 update() 或原始SQL):

  • If writes can come from anywhere (for example, using update() or raw SQL):

    您需要数据库级约束。 Django没有为此提供模型级别的支持,但是您可以通过编写自定义迁移并使用 RunSQL 创建约束来创建一个。

    You need a database-level constraint. Django has no model-level support for this, but you could create one by writing a custom migration and using RunSQL to create the constraint.

    其中我认为2是标准的,如果您不需要3和4的保护,则是最优雅的。

    Of these I would consider 2 to be standard, and the most elegant if you don't need the protections of 3 and 4.

    这篇关于确保字段在Django中始终为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆