Skip to content

Instantly share code, notes, and snippets.

@amites
Created February 24, 2017 22:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amites/8b24df066e52bba2642d10e9a074b2a1 to your computer and use it in GitHub Desktop.
Save amites/8b24df066e52bba2642d10e9a074b2a1 to your computer and use it in GitHub Desktop.
Why do I get a different result from `getattr` and a direct attribute call?
# function being called
# Use case is within a migration
# apps = `from django.apps import apps` -- within a migration
# model_name = str lowercase model name
def blob_to_file(apps, model_name, text_field_name, file_field_name):
"""
Upload existing TextField json blobs to files.
"""
model = apps.get_model("answers", model_name)
for obj in model.objects.all():
blob = getattr(obj, text_field_name)
if not blob:
blob = '{}'
file_field = getattr(model, file_field_name)
f = StringIO()
f.write(blob)
f.seek(0)
try:
file_field.field.save('{}.json'.format(obj.pk), File(f), save=True)
except Exception as e:
print(e.message)
import ipdb
ipdb.set_trace()
obj.save()
f.close()
# output from use within ipdb
"""
ipdb> file_field_name
u'answers_file'
ipdb> file_field = getattr(model, file_field_name)
ipdb> file_field.save('{}.json'.format(obj.pk), File(f), save=True)
*** AttributeError: 'FileDescriptor' object has no attribute 'save'
ipdb> obj.answers_file.save('{}.json'.format(obj.pk), File(f), save=True)
ipdb> obj.answers_file == getattr(model, 'answers_file')
False
"""
@TrueNorthTrent
Copy link

Did you ever figure out the answer? I'm running into this now =)

@TrueNorthTrent
Copy link

I figured it out after playing around -- I realized that in this line:

" file_field = getattr(model, file_field_name)"

model needs to equal the model-object, not the imported model.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment