views:

40

answers:

2

Within Django, can a function local to a model be called on object creation to dynamically fill a field?

class someModel(models.Model):
    id = models.FloatField(primary_key=True, default=generate_id())

    def generate_id(self):
        newId=time.time()
        return newId

So far I haven't had any luck with getting it to work or with locating documentation that covers it.

+1  A: 

Yeah, this can be done using the signals framework.

from django.db import models
from django.core.signals import post_init

class SomeModel(models.Model):
    pass # *snip*

def generate_id(sender, **kwargs):
    kwargs.get('instance').newId = time.time()
        # ...

post_init.connect(SomeModel.generate_id)
Aviral Dasgupta
Thanks for the tip, I've been meaning to investigate signals for a while now!
danspants
Signals are designed to provide plug-in points for the third party. There is no reason to use them inside one application. It would be performance impact if compared to more straight-forward approach. See my answer bellow for details.
uptimebox
+1  A: 
from django.db import models
import time

class SomeModel(models.Model):
    id = models.FloatField(primary_key=True)

    def save(self, *args, **kwargs):
       if not self.id:
           self.id = self.generete_id()
       super(SomeModel, self).save(*args, **kwargs)

    def generate_id(self):
       return time.time()

Also be warned that there may be some code in Django internals that relies on the fact that unsaved model instance has no primary key (at least it was the case in v1.0).

Another pitfall is generating id by calling time.time(). Chanses are that you'll get duplicate ids under heavy load. I'd suggest using uuid module to generate unique identifiers.

uptimebox