Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call method once to set multiple fields in Django Rest Framework serializer

How can I call the same method one time to set multiple fields with a Django Rest Framework serializer? This is what I do now but this clearly calls the method two times. How can I limit it to only be called once?

class MyModel(models.Model):
    def GetTwoValues(self):
        foo = []
        bar = []

        # expensive operation

        return foo, bar

class MyModelSerializer(serializers.HyperlinkedModelSerializer):
    foo = serializers.SerializerMethodField()
    bar = serializers.SerializerMethodField()

    def get_foo(self, obj):
        foo, _ = obj.GetTwoValues()
        return foo

    def get_bar(self, obj):
        _, bar = obj.GetTwoValues()
        return bar

    class Meta:
        model = MyModel
        fields = ('FirstValue', 'SecondValue',)
like image 849
Oskar Persson Avatar asked Nov 17 '16 19:11

Oskar Persson


People also ask

How do you pass extra context data to Serializers in Django REST framework?

In function based views we can pass extra context to serializer with "context" parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with "self. context". From example, to get "exclude_email_list" we just used code 'exclude_email_list = self.

What is the difference between ModelSerializer and HyperlinkedModelSerializer?

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.

What does serializer save () do?

So everytime you call Serializer's save() , you get an instance of whatever data you are serializing. comment here is an instance. Passing an instance in a serializer is telling the serializer that you want to update this instance. So calling save will then call self.

How do I pass Queryset to serializer?

To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.

What is serializer in Django rest?

Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

How to create REST API in Django?

For creating rest API in Django make sure you have installed Django and Django rest framework in your virtual environment. For installation, you can visit Django and Django rest framework websites. Once installation is done create your project and app. In my case, my Project name is DProject and my app name is API .

How do serializers work in the rest framework?

The serializers in REST framework work very similarly to Django's Form and ModelForm classes. We provide a Serializer class which gives you a powerful, generic way to control the output of your responses, as well as a ModelSerializer class which provides a useful shortcut for creating serializers that deal with model instances and querysets.

How many types of fields are there in Django models?

There are four major fields – DateTimeField, DateField, TimeField and DurationField. DateTimeField is a serializer field used for date and time representation. It is same as – DateTimeField – Django Models


1 Answers

There are a few options:

1) Store the values so that the expensive method is called only once. E.g.:

def _get_two_values(self, obj):
    if not hasattr(self, '_two_values'):
        self._two_values = obj.GetTwoValues()
    return self._two_values

def get_foo(self, obj):
    foo, _ = self._get_two_values(obj)
    return foo

def get_bar(self, obj):
    _, bar = self._get_two_values(obj)
    return bar

2) Remove both fields from the serializer and assign both values in the serializer's to_representation method. E.g.:

def to_representation(self, obj):
    data = super().to_representation(obj)
    foo, bar = obj.GetTwoValues()
    data['foo'] = foo
    data['bar'] = bar
    return data
like image 86
lucasnadalutti Avatar answered Oct 06 '22 18:10

lucasnadalutti