1

I have the following situation

class MyModel(models.Model):
    key = models.CharField(max_length=255)
    value = models.TextField(max_length=255)
    category = models.CharField(max_length=4)
    mode = models.CharField(max_length=4)

the fields key, category and mode are unique together. I have the following objects:

    m1 = MyModel(key='MODEL_KEY', value='1', category='CAT_1' mode='MODE_1')
    m2 = MyModel(key='MODEL_KEY', value='2', category='CAT_1' mode='MODE_2')
    m3 = MyModel(key='MODEL_KEY', value='1', category='CAT_2' mode='MODE_1')
    m4 = MyModel(key='MODEL_KEY', value='2', category='CAT_2' mode='MODE_2')

I want to expose an API that will group by key and category so the serialized data will look something like this:

{
    "key": "MODEL_KEY",
    "category": "CAT_1"
    "MODE_1": { "id": 1, "value": "1" }
    "MODE_2": { "id": 2, "value": "2" }
},
{
    "key": "MODEL_KEY",
    "category": "CAT_2"
    "MODE_1": { "id": 3, "value": "1" }
    "MODE_2": { "id": 4, "value": "2" }
}

Is there any way of doing this in django rest framework with ModelSerializer.

1 Answer 1

1

There is module that allows you to group Django models and still work with a QuerySet in the result: https://github.com/kako-nawao/django-group-by

Using the above to form your queryset:

# Postgres specific!
from django.contrib.postgres.aggregates.general import ArrayAgg

qs = MyModel.objects.group_by('key', 'category').annotate(
        mode_list=ArrayAgg('mode')).order_by(
        'key', 'category').distinct()

You can then access the properties key, category and mode_list on the resulting QuerySet items as attributes like qs[0].mode_list. Therefore, in your serializer you can simply name them as fields.

The model_list field might require a SerializerMethodField with some custom code to transform the list.

Note that you need an aggregation if you don't want to group by mode, as well.

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.