简体   繁体   English

如果设置为null,如何创建具有默认值的Django模型字段

[英]How to create a django model field that has a default value if ever set to null

Given a model 给定一个模型

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

How can I arrange it so that any access to colour either returns the value stored in the field, or if the field is blank/null then it returns red? 我该如何安排它,以便对颜色的任何访问都返回存储在字段中的值,或者如果该字段为空白/空则返回红色?

The

default=red
will put "red" in the field when it's first created, but if it's then edited to blank I'd like access to it to return "red", not "" 会在首次创建时将“红色”放置在字段中,但是如果将其编辑为空白,我想访问它以返回“红色”,而不是“”

Updated: I tried the properties solution suggested below, but I'm using JSON serialisation to implement a REST API and the properties (eg colour ) don't get serialised, and serialising the _colour breaks the API 更新:我尝试了下面建议的属性解决方案,但是我正在使用JSON序列化实现REST API,并且属性(例如colour )没有被序列化,而_colour序列化_colour破坏API

You can create a separate method instead: 您可以改为创建一个单独的方法:

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

An alternative is to use property. 另一种方法是使用属性。

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

Use the save method to implement this. 使用save方法来实现这一点。

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

Here's how I ended up solving this problem. 这就是我最终解决此问题的方法。

First some preconditions: I have existing code that accesses these field names (eg 'colour') and the field is also serialised (by django-rest-interface) as part of an API. 首先要满足一些先决条件:我已有访问这些字段名称的代码(例如“ colour”),并且该字段也作为API的一部分进行了序列化(通过django-rest-interface)。 Neither of these things can be changed. 这些事情都不能改变。

Trying the properties method worked fine, except that colour was no longer a field so didn't get serialised. 尝试使用properties方法可以很好地工作,除了colour不再是字段,因此不进行序列化。 Result: broken API 结果:API损坏

Then moved to the save() solution, along with a custom attribute on each field which should behave like this: 然后移到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)

Now all works fine and as required. 现在一切正常,并按要求进行。

The only problem with this solution is that if the default values change it's impossible to tell which database fields should have updated defaults, and which are just accidentally the same colour as the old default. 此解决方案的唯一问题是,如果更改了默认值,则无法确定哪些数据库字段应具有更新的默认值,以及哪些字段与旧的默认值偶然具有相同的颜色。 However for my application I can live with this. 但是对于我的应用程序,我可以接受。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM