Reputation: 219
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
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
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