foebu
foebu

Reputation: 1415

How to update dynamically a model in Django?

I want to fill my django model from a csv. I upload the csv with numpy and then, since my model fields are called like the column headers of the csv, I would like to do something like this:

data=np.genfromtxt("file.csv", delimiter=',', dtype=None, names=True)
columns = data.dtype.names
for i in range(len(data['id'])):
    for a in range(1, len(columns)): #1 
        p=MyModel.objects.filter(columns[a]=data[i][columns[a]])
            p.save()

Now, this is quite row, and it doesn't work because I can't pass that columns[a] instead of the field name.

I even tried something like MyModel._meta_fields[a]=data[i][a].

I have tens or even hundreds of fields, sometimes: isn't there an elegant solution that would me spare to write e long list of field names?

Thank you!

Upvotes: 3

Views: 901

Answers (2)

Blair
Blair

Reputation: 15808

If you are trying to create new instances of your model from each row of the data, use the setattr function to set the values:

data=np.genfromtxt("file.csv", delimiter=',', dtype=None, names=True)
columns = data.dtype.names
for i in range(len(data['id'])):
    p = MyModel()
    for a in range(1, len(columns)): #1
        if hasattr(p, columns[a]):
            setattr(p, columns[a], data[i][columns[a]])
        else:
            raise AttributeError("'MyModel' object has no attribute '{0}'".format(columns[a]))
    p.save()

Upvotes: 3

SoylentFuchsia
SoylentFuchsia

Reputation: 1181

You could consider constructing a dictionary of the arguments you want to pass, and then use ** to supply the dictionary to the function as those arguments.

column_args_dict = {columns[a]: data[i][columns[a]]}
p = MyModel.objects.filter(**column_args_dict)

Upvotes: 1

Related Questions