3

One of my app's models has a few pre-defined fields, let's say:

class Data(models.Model)
    user = models.CharField(max_length=50)
    date = models.DateTimeField()

It also has a few fields that are based on variables passed in to the methods of a class which I would like to name "method_variable". Below is a sample class from which I would like to add meth0_var0 and meth0_var1 as CharFields in the Data model.

class A:
    def meth0(self, var0, var1)
       ...

I would like to dynamically add those variables to my model whenever I migrate the database (basically just saving myself the labor of writing out all the fields as there are many). So far I have tried adding this to my models.py after defining the model:

methods = {k: v for k, v in dict(A.__dict__).items() if '__' not in k} # get rid of __init__ and such
for key in methods:
    args = [arg for arg in getfullargspec(methods[key]).args if arg != 'self'] # get rid of self / methods that don't have any input variables
    [setattr(Data, f'var_{key}_{arg}', models.CharField(max_length=50, default='Unrecorded')) for arg in args] # use what's left to create attributes in the class for migration

When I try to run makemigrations it finds no new fields and therefore doesn't migrate. How is setattr different from writing out the field myself, or what part of django migration ignores the attributes I add dynamically?

toastyrye
  • 31
  • 3
  • "_saving myself the labor of writing out all the fields as there are many_" this would mostly imply that your database schema is not normalized. Back to the drawing board for you ;). Please research about [Database normalization](https://en.wikipedia.org/wiki/Database_normalization). – Abdul Aziz Barkat Jul 17 '21 at 06:44
  • I'm actually trying to make sure the database is normalized here. It's analog telemetry data so each record is automatically unique - I'm trying to make sure I'm not lazily saving these variables into a json field. Since it's analog data using foreign keys doesn't make a ton of sense as far as I can tell. There are no transitive functional dependencies between sensors. – toastyrye Jul 19 '21 at 15:43

1 Answers1

3

Kind of duplicate of Programmatically specifying Django model attributes

See this answer https://stackoverflow.com/a/2501419

Seems add_to_class has more logic than just using setattr:
https://github.com/django/django/blob/1eaf38fa87384fe26d1abf6e389d6df1600d4d8c/django/db/models/base.py#L324
Mainly also doing a call to cls._meta.add_field through contribute_to_class

c4ffein
  • 73
  • 1
  • 7