Login or Sign up

Instantiate a class by calling it with a dirty dictionary b/c you are using Django with some substandard API

Posted by: skyl on May 9, 2010

Say you have a model class that has a ton of fields. It may be for logging the response from some crappy API. You no longer want to instantiate the model with the 60 +/- keywords; you just want to unpack your response dictionary into the model and save it.

d = response_from_api_call_as_dictionary
response_log = ResponseLog(
    user=myuser, created=now, foo=bar,
    **d # just unpack the dictionary as kwargs
)

You find that this usually works. But sometimes, this crazy API (that really is an embarrassment for the multi-billion dollar company that publishes it) gives you some field that is not one of the many that you defined. You get:

TypeError: 'baz' is an invalid keyword argument for this function

You now realize that this would be a perfect use case for a couchdb or other nosql database but you don't have time for that right now. You're locked into SQL and the Django ORM at the moment. Let's just throw away the items in the dictionary that do not correspond to fields in our model.

def clean_dict(d, modelclass):
    '''to be able to instantiate the model class with **d, remove keys that are not fields'''
    ret = d.copy()
    for k in ret.keys():
        if k not in [f.name for f in modelclass._meta.fields]:
            del ret[k]

    return ret

d = response_from_api_call_as_dictionary
safe_dict = clean_dict(d, ResponseLog)

response_log = ResponseLog(**safe_dict)

Sometimes you just need a dirty hack to get on with the mission at hand.

Comments on This Post:

Please Login (or Sign Up) to leave a comment