简体   繁体   中英

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

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/

Use the save method to implement this.

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. 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. Result: broken API

Then moved to the save() solution, along with a custom attribute on each field which should behave like this:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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