【问题标题】:How to create a django model field that has a default value if ever set to null如果曾经设置为 null,如何创建具有默认值的 django 模型字段
【发布时间】:2011-01-10 12:36:31
【问题描述】:

给定一个模型

class Template(models.Model):
    colour = models.CharField(default="red", blank = True, null=True)

如何安排它,以便对颜色的任何访问都返回存储在字段中的值,或者如果该字段为空白/空,则返回红色?

default=red
将在首次创建时将“red”放入该字段,但如果随后将其编辑为空白,我希望访问它以返回“red”,而不是“”

更新:我尝试了下面建议的属性解决方案,但我正在使用 JSON 序列化来实现 REST API,并且属性(例如 colour)不会被序列化,并且序列化 _colour 会破坏 API

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    使用save 方法来实现。

    def save( self, *args, **kw ):
        if self.colour is None:
            self.colour= 'red'
        super( ThisModel, self ).save( *args, **kw )
    

    【讨论】:

    • 这会修改存储的值,这不是我想要发生的事情
    【解决方案2】:

    您可以创建一个单独的方法:

    def get_colour(self):
        if not self.colour:
            return 'red'
        else:
            return self.colour
    

    另一种方法是使用属性。

    http://www.djangoproject.com/documentation/models/properties/

    【讨论】:

    • 我更喜欢这个解决方案,因为它不会修改模型字段的值。除非您想要修改该字段。
    • 我无法更改我的代码以在任何地方通过 get_colour 访问该字段 - 所以所有读/写都必须通过颜色。属性看起来可以工作。有什么简单的方法可以生成大量重复的属性函数(我在模型中有很多颜色字段,每个都需要包装)
    • @Malcolm Box:处理您对大量颜色字段的要求的更好方法是拥有一个抽象类,该类具有在许多模型之间共享的适当属性(颜色和您可能拥有的任何其他属性) .见:docs.djangoproject.com/en/dev/topics/db/models/#id6
    • @celopes - 看不到抽象基类在这里有什么帮助,我仍然需要包装这些字段。事实证明,编写一个通用的 getter 和 setter 函数很容易,那么每个属性行就是 field = property(lambda x: x._getter('field'), lambda x,y : x.setter('field', y))
    • @Malcolm Box:我并没有提议将其作为您问题的解决方案——这就是为什么它只是一个评论而不是您问题的答案。我指出,每当您在多个模型中拥有相同的属性时,最好将其抽象为一个共同的祖先。它消除了代码中的重复。不必在多个模型中编写相同的属性,您只需在抽象基类中实现它。
    【解决方案3】:

    这就是我最终解决这个问题的方法。

    首先一些先决条件:我有访问这些字段名称(例如“颜色”)的现有代码,并且该字段也被序列化(通过 django-rest-interface)作为 API 的一部分。这些东西都不能改变。

    尝试使用 properties 方法效果很好,只是 colour 不再是一个字段,因此没有被序列化。结果:API 损坏

    然后转到 save() 解决方案,以及每个字段的自定义属性,其行为应如下所示:

    class ColourChoices(models.Model):
        colour1 = models.CharField()
        colour1.colour_default = "red"
        colour2 = models.CharField()
        colour2.colour_default = "blue"
    
        def save(self, *args, **kwargs):
            # force colour fields to default values
            for f in [ x for x in self._meta.fields if hasattr(x, 'colour_default') ]:
                if self.__getattribute__(f.attname) == "":
                    self.__setattr__(f.attname, f.colour_default)
           super(ColourChoices, self).save(*args,**kwargs)
    

    现在一切正常并按要求工作。

    此解决方案的唯一问题是,如果默认值发生更改,则无法判断哪些数据库字段应该更新默认值,以及哪些字段的颜色会意外地与旧默认值相同。但是对于我的应用程序,我可以忍受这个。

    【讨论】:

      猜你喜欢
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-29
      • 1970-01-01
      • 2021-03-26
      相关资源
      最近更新 更多