0

Context

I have an API endpoint api/v1/checkin/ that returns the current DeviceGroup and the AppVersions for an App that have to be active.

Problem

The endpoint currently returns data along with the correctly filtered AppVersions like this:

{
    "customer_device_uuid": "8d252b78-6785-42ea-9aee-b6f9e0f870b5",
    "device_group": {
        "group_uuid": "869b409d-f281-492e-bb62-d3168aea4394",
        "device_group_name": "Default",
        "color": "#0a2f45",
        "is_default": true,
        "app_versions": [
            "2.0",
            "1.1"
        ]
    }
}

Goal

I want the app_versions in the response to contain more data like this:

{
    "customer_device_uuid": "8d252b78-6785-42ea-9aee-b6f9e0f870b5",
    "device_group": {
        "group_uuid": "869b409d-f281-492e-bb62-d3168aea4394",
        "device_group_name": "Default",
        "color": "#0a2f45",
        "is_default": true,
        "app_versions": [
            {
                "app_version_uuid": "UUID here",
                "app_version_name": "1.1",
                "package_id": "package name here",
                "auto_start": false,
                "version_code": 1,
                "version_name": "0.1",
                "source": "link to file here"
            }, ...
        ]
    }
}

Serializers

# serializers.py


class AppVersionSerializer(serializers.ModelSerializer):
    auto_start = serializers.BooleanField(source='app_uuid.auto_start')

    class Meta:
        model = AppVersion
        fields = ('app_version_uuid', 'app_version_name', 'package_id', 'auto_start', 'version_code', 'version_name',
                  'source')


class DeviceGroupSerializer(serializers.ModelSerializer):
    app_versions = serializers.SerializerMethodField(read_only=True)

    # filters the app versions per app
    def get_app_versions(self, model):
        qs = model.get_current_app_versions()
        return [o.app_version_name for o in qs]

    class Meta:
        model = DeviceGroup
        fields = ('group_uuid', 'device_group_name', 'color', 'is_default', 'app_versions')


class CheckinSerializer(serializers.ModelSerializer):
    device_group = DeviceGroupSerializer(many=False, read_only=True, source='group_uuid')

    class Meta:
        model = CustomerDevice
        fields = ('customer_device_uuid', 'customer_uuid', 'device_id_android', 'device_group')
        extra_kwargs = {
        'customer_uuid': {'write_only': True},
        'device_id_android': {'write_only': True}
    }

I am guessing that I have to change the get_app_versions() in order to achieve my goal but I have no idea how.

What should I change in order to get the response I want?

EDIT

The get_current_app_versions method that does the filtering

# models.py

def get_current_app_versions(self):
    return (
        AppVersion.objects
        .filter(appversiondevicegrouplink__release_date__lt=timezone.now())
        .filter(appversiondevicegrouplink__device_group=self)
        .order_by('app_uuid__app_uuid', '-appversiondevicegrouplink__release_date')
        .distinct('app_uuid__app_uuid')
    )

1 Answer 1

1

You are correct in assuming that you will have to change get_app_versions and instead of returning a list in the line return [o.app_version_name for o in qs] you will need to return a list of dictionaries.

You will need to create a full serializer for the AppVersions model. and then in your get_app_versions properly serialize you return values by passing them into your new serializer which contains all the fields you would like to return return AppVersionSerializer2(qs, many=True).data.

You may have to override serialization of certain fields as they may not be handled well by the serializer automatically.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your reply. The qs returns an AppVersion object and results in a TypeError. I updatet my question and added the get_app_versions method.
you need to serialize the qs that is being returned. One of the fields cannot be serialized, which is likely why you are getting a TypeError - can you posyt the full model as well?

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.