Is there an automagic way of passing verbose_name and help_text to json?

1,020 views
Skip to first unread message

George Mamalakis

unread,
Feb 13, 2014, 10:01:44 AM2/13/14
to django-res...@googlegroups.com
Hi all,

I am trying to pass verbose_name and help_text through my json api, using ModelViewSets and ModelSerializers. Is there an automated way to do it or do I have to return them via SerializerMethodFields? The latter would cost a lot of coding.

Thanx all in advance!

George Mamalakis

unread,
Feb 14, 2014, 8:54:16 AM2/14/14
to django-res...@googlegroups.com
OK,

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:

cls.base_fields['%s_label' % x.name] = serializers.SerializerMethodField('get_%s_label' % x.name)
cls.base_fields['%s_help' % x.name] = serializers.SerializerMethodField('get_%s_help' % x.name)

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.

George Mamalakis

unread,
Feb 14, 2014, 9:14:30 AM2/14/14
to django-res...@googlegroups.com
Ooops,

I had a spelling mistake. The correct code when adding help_text is the following:

if x.help_text:
            setattr(cls, '%s_help' % x.name, serializers.SerializerMethodField('get_%s_help' % x.name))
            setattr(cls, 'get_%s_help' % x.name, create_fun(x.help_text))
            additional_fieldnames.append('%s_help' % x.name)


On Thursday, February 13, 2014 5:01:44 PM UTC+2, George Mamalakis wrote:

Vermus Rus

unread,
Apr 18, 2015, 10:09:14 AM4/18/15
to django-res...@googlegroups.com

Any news? we steel need this approach in 2015?

пятница, 14 февраля 2014 г., 17:14:30 UTC+3 пользователь George Mamalakis написал:

Vermus Rus

unread,
Apr 18, 2015, 12:47:15 PM4/18/15
to django-res...@googlegroups.com



суббота, 18 апреля 2015 г., 17:09:14 UTC+3 пользователь Vermus Rus написал:

George Mamalakis

unread,
Apr 18, 2015, 1:04:18 PM4/18/15
to django-res...@googlegroups.com

Hi Vermus,

I don't know if this has been addressed by the django-rest team, in my case, though, I finally resolved it using a different (smaller) decorator than the one I posted in this thread (if I remember correctly). If you want to, I can post it here when I go to work on Monday.

--
You received this message because you are subscribed to a topic in the Google Groups "Django REST framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-rest-framework/blLRIL495_o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-rest-fram...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages