3

Given that I have a model like this:

class Case(models.Model):
    opened = models.DateTimeField(auto_now_add=True)
    client_first_name = models.CharField(max_length=50)
    client_last_name = models.CharField(max_length=50)

I would like to group the client_* fields, so that the serialized JSON would look like this:

{
    "opened": "2014-10-05T19:30:48.667Z",
    "client": {
        "first_name": "John",
        "last_name": "Doe"
    }
}

The following I tried, but doesn't work because client is not an actual field:

class ClientSerializer(serializers.ModelSerializer):

    class Meta:
        model = Case
        fields = ('client_first_name', 'client_last_name')


class CaseSerializer(serializers.ModelSerializer):
    client = ClientSerializer()

    class Meta:
        model = Case
        fields = ('opened', 'client')

What options do I have except for completely manual serialization? I prefer not to make a separate model for Client because this data really belongs in Case. Read-only is not good enough.

4
  • There is an answer. stackoverflow.com/questions/28187476/…. Commented Sep 20, 2016 at 7:44
  • @brawaga It's not really an answer since it's "completely manual serialization" and I wrote I'm looking for other options than that. Thanks anyway; good to have the author's opinion on it. Commented Sep 20, 2016 at 11:00
  • @Dien, based on not an answer, but top post update in the bottom, you can build a solution not to violate DRY, and that will be not completely, but half-manual serialization, just because the solution is to manipulate validated_data and instance and probably some more. And it will work two-way. Commented Sep 21, 2016 at 7:50
  • @brawage Ah, you're right – I took 'answer' too literally. There might be something in there. Although I agree with Tom that his version is more readable. Commented Sep 21, 2016 at 12:09

1 Answer 1

3

You can try like this:

class CaseSerializer(serializers.ModelSerializer):
    client = serializers.SerializerMethodField('client')

    class Meta:
        model = Case
        fields = ('opened', 'client')

    def client(self, obj):
        client_fields = {}
        client_fields['first_name'] = obj.client_first_name
        client_fields['last_name'] = obj.client_last_name
        return client_fields
Sign up to request clarification or add additional context in comments.

2 Comments

It didn't work exactly, but I got the idea. Unfortunately it's inherently read-only, and I need full CRUD support.
Dooh! I forgot it. Yes, the SerializerMethodField is read-only. I have made a heavy use of it, but for read-only web services, so I didn't think immediately that you would also need post and put methods.

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.