Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating Django model fields dynamically from method variables during migration

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?

like image 288
toastyrye Avatar asked Nov 03 '25 11:11

toastyrye


1 Answers

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

like image 153
c4ffein Avatar answered Nov 06 '25 03:11

c4ffein