noplacetoh1de
noplacetoh1de

Reputation: 219

How to call the property method in a dynamic Django model?

I have a problem with calling a property() inside a dynamic model in Django. I need an additional field, which gives me a log-transformed value of an existing field of a database-table. For further processing the field must be accessible through the model structure. The name of the database-table will be defined during runtime, so that I need a dynamic model.

This is my model definition:

def create_model(self, name, libs=None, app_label='gotool', module='', options=None, admin_opts=None):
    fields = {
        'database_id': models.CharField(max_length=255, primary_key=True),
        'description': models.TextField(blank=True),
        'l1_normalized': models.FloatField(null=True, blank=True),
        'l2_normalized': models.FloatField(null=True, blank=True),
        'pvalue': models.FloatField(null=True, blank=True),
        'log2fc': models.FloatField(null=True, blank=True),
        'goterm': models.TextField(db_column='GOTerm', blank=True),
        '_get_l1_logcount': lambda self: numpy.log10(self.l1_normalized),
        # here is my problem:       
        'l1_s_logcount': property(_get_l1_logcount), # I don't know how to call the property-method inside the dynamic model definition
    }

    class Meta:
        pass

    if app_label:
        setattr(Meta, 'app_label', app_label)

    if options is not None:
        for key, value in options.iteritems():
            setattr(Meta, key, value)

    attrs = {'__module__': module, 'Meta': Meta}

    if fields:
        attrs.update(fields)

    model = type(name, (models.Model,), attrs)

    if admin_opts is not None:
        class Admin(admin.ModelAdmin):
            pass
        for key, value in admin_opts:
            setattr(Admin, key, value)
        admin.site.register(model, Admin)

    return model

Many thanks for your help!

Upvotes: 1

Views: 3156

Answers (2)

okm
okm

Reputation: 23871

Also you could take out the function and use it directly

get_l1_logcount = lambda self: numpy.log10(self.l1_normalized)

fields = {
    ...,
    '_get_l1_logcount': get_l1_logcount,    
    'l1_s_logcount': property(get_l1_logcount),
}

Upvotes: 0

Chris Morgan
Chris Morgan

Reputation: 90742

Think about a way in which you could implement it in a class:

class X(object):
    def get_y(self):
        return self.y

If you were wanting to create a property y without actually using the function get_y as it stands at that point, how might you do it?

class X(object):
    def get_y(self):
        return self.y

    @property
    def y(self):
        return self.get_y()

This way it is evaluated at runtime.

'l1_s_logcount': property(lambda self: self._get_l1_logcount()),

Or, cutting out the intermediate step,

'l1_s_logcount': property(lambda self: numpy.log10(self.l1_normalized)),

Upvotes: 2

Related Questions