1

am trying to build a serializer using HyperlinkedModelSerializer, yet I have a scenario where I want to add a field which does not exist in the model but I will require the value for validating the transaction, I found the below snippet

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from rest_framework import serializers
import logging

# initiate logger
logging.getLogger(__name__)


class PostHyperlinkedModelSerializerOptions(serializers.HyperlinkedModelSerializerOptions):
    """
   Options for PostHyperlinkedModelSerializer
   """

    def __init__(self, meta):
        super(PostHyperlinkedModelSerializerOptions, self).__init__(meta)
        self.postonly_fields = getattr(meta, 'postonly_fields', ())


class PostHyperlinkedModelSerializer(serializers.HyperlinkedModelSerializer):
    _options_class = PostHyperlinkedModelSerializerOptions

    def to_native(self, obj):
        """
       Serialize objects -> primitives.
       """
        ret = self._dict_class()
        ret.fields = {}

        for field_name, field in self.fields.items():
            # Ignore all postonly_fields fron serialization
            if field_name in self.opts.postonly_fields:
                continue
            field.initialize(parent=self, field_name=field_name)
            key = self.get_field_key(field_name)
            value = field.field_to_native(obj, field_name)
            ret[key] = value
            ret.fields[key] = field
        return ret

    def restore_object(self, attrs, instance=None):
        model_attrs, post_attrs = {}, {}
        for attr, value in attrs.iteritems():
            if attr in self.opts.postonly_fields:
                post_attrs[attr] = value
            else:
                model_attrs[attr] = value
        obj = super(PostHyperlinkedModelSerializer,
                    self).restore_object(model_attrs, instance)
        # Method to process ignored postonly_fields
        self.process_postonly_fields(obj, post_attrs)
        return obj

    def process_postonly_fields(self, obj, post_attrs):
        """
       Placeholder method for processing data sent in POST.
       """
        pass

class PurchaseSerializer(PostHyperlinkedModelSerializer):
    """ PurchaseSerializer
    """
    currency = serializers.Field(source='currency_used')

    class Meta:
        model = DiwanyaProduct
        postonly_fields = ['currency', ]

Am using the above class, PostHyperlinkedModelSerializer, but for some reason the above is causing a problem with the browsable api interface for rest framework. Field labels are disappearing, plus the new field "currency" is not showing in the form (see screenshot below for reference). Any one can help on that?

enter image description here

1 Answer 1

2

Whoever wrote the code probably didn't need browsable api (normal requests will work fine).

In order to fix the api change to_native to this:

def to_native(self, obj):
    """
    Serialize objects -> primitives.
    """
    ret = self._dict_class()
    ret.fields = self._dict_class()

    for field_name, field in self.fields.items():

        if field.read_only and obj is None:
            continue

        field.initialize(parent=self, field_name=field_name)
        key = self.get_field_key(field_name)
        value = field.field_to_native(obj, field_name)

        method = getattr(self, 'transform_%s' % field_name, None)
        if callable(method):
            value = method(obj, value)

        if field_name not in self.opts.postonly_fields:
            ret[key] = value

        ret.fields[key] = self.augment_field(field, field_name, key, value)
    return ret
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.