I wrote a decorator to achieve the behaviour I was looking for as a PoC (which is definitely not final/stable/optimal):
def add_label_and_help(cls):
'''
add_label_and_help() decorates a ModelSerializer class (cls) with the appropriate attributes and methods that
return the label and help_text of each model field.
'''
def create_fun(arg):
def f(self, instance, arg=arg):
return arg
return f
Meta = None
has_meta_fields = False
if hasattr(cls, 'Meta'):
Meta = cls.Meta
class_fields = cls.Meta.model._meta.fields
fields = class_fields
if Meta is not None:
if hasattr(Meta, 'fields'):
meta_field_names = Meta.fields
has_meta_fields = True
fields = [x for x in fields if
x.name in meta_field_names]
additional_fieldnames = []
for x in fields:
if x.name.lower() == 'id':
continue
if x.verbose_name:
setattr(cls, '%s_label' %
x.name, serializers.SerializerMethodField('get_%s_label' %
x.name))
setattr(cls, 'get_%s_label' %
x.name, create_fun(x.verbose_name))
additional_fieldnames.append('%s_label' %
x.name)
cls.base_fields['%s_label' %
x.name] = serializers.SerializerMethodField('get_%s_label' %
x.name)
if x.help_text:
setattr(cls, '%s_help' %
x.name, serializers.SerializerMethodField('get_%s_help' %
x.name))
setattr(cls, 'get_%s_label' %
x.name, create_fun(x.help_text))
additional_fieldnames.append('%s_help' %
x.name)
cls.base_fields['%s_help' %
x.name] = serializers.SerializerMethodField('get_%s_help' %
x.name)
if has_meta_fields:
cls.Meta.fields = tuple(list(cls.Meta.fields) + additional_fieldnames)
return cls
What surprised me was that without the two lines that add the two newly created fields in class' base_fields, the code would return an error like the following:
KeyError at /inventorydd/
'start_text_label'
| Request Method: | GET |
|---|
| Request URL: | http://localhost:8000/inventorydd/ |
|---|
| Django Version: | 1.6.1 |
|---|
| Exception Type: | KeyError |
|---|
| Exception Value: | 'start_text_label' |
|---|
| Exception Location: | /usr/lib/python2.7/site-packages/rest_framework/serializers.py in get_fields, line 244
|
|---|
I tried debugging it with not much luck, hence I included the two lines:
I understand that this is not the best way of achieving my goal, but at least it's a start. If someone wishes to help me make it more robust and rest-framework "compatible", please feel free.
Thanks all again for your help.