tags:

views:

68

answers:

2

Using Django, how do I generate the value of a field the first time it's accessed? Then storing the value on the field.

In my case it's an image, but it could be anything I suppose. What I need is a function that runs before the field is accessed or wrapping the access and upon checking for nullness I generate it, or something like that.

+1  A: 

Is there any reason why you couldn't do it when the object is saved? Because that would be trivially easy to accomplish by overriding the save method in the relevant model, for instance:

def save(self, force_insert=False, force_update=False):
    if not self.image:
        self.image = foo
    super(RelevantModel, self).save(force_insert, force_update)

Of course, if there is a relevant difference for you between the time that the object is first saved and the time that a particular field is first accessed, then this doesn't solve your problem.

ozan
There are two reasons why I don't want to do that: 1) this is generated data and it should be possible to delete this data and get it regenerated on demand (if the generating algorithm is improved, or this data is not backed up).
J. Pablo Fernández
2) because to generate this new image I need an image in the same record which means that I have to validate the form, record it and then do the generation, and if the generation fails then I'm left with a validate broken record. It makes more sense to generate it at request-time.
J. Pablo Fernández
+3  A: 

There's been a getters and setters ticket open in the djangoproject for a couple years now, but no luck. I've seen three common approaches to the situation you describe:

  • Put your model field at a different name, say image_field, and write a getter/setter pair (using python's property syntax) called image in your object that queries that field. This will work for casual use by your functions, but any calls from within the framework itself will obviously ignore your getter/setter.

  • Create your own custom field subclass to work the magic for you if possible.

  • Override save as ozanonay suggests.

Jarret Hardie