def instance_dict(instance, key_format=None):
"Returns a dictionary containing field names and values for the given instance"
from django.db.models.fields.related import ForeignKey
if key_format:
assert '%s' in key_format, 'key_format must contain a %s'
key = lambda key: key_format and key_format % key or key
d = {}
for field in instance._meta.fields:
attr = field.name
value = getattr(instance, attr)
if value is not None and isinstance(field, ForeignKey):
value = value._get_pk_val()
d[key(attr)] = value
for field in instance._meta.many_to_many:
d[key(field.name)] = [obj._get_pk_val() for obj in getattr(instance, field.attname).all()]
return d
Comments
Ticket #5126 has a patch for including this functionality in Django.
#
The function didn't handle dates correctly, at least when feeding instance data to a form with a SelectDateWidget.
I also wanted to use it for unsaved objects, but they failed on many-to-many fields.
Here's a version which fixes both these problems:
#
I've wanted one that could traverse foreign keys.
This adds on the date improvement version above and is tested on django 1.4.
Foreign keys come back as foreignkeyname.foreignkeyvalue in the dictionary, it's recursive so will pull back all the relations (only tested with one level of foreignkey).
#
This turned out to be incompatible with django-filer so I've added a hasattr test.
Now tested + working on django 1.4.1
#
Oops missed a bit :)
#
At some time my editor has eaten the pk value - here it is restored.
#