Джанго вложенный сериализатор с serializermethodfield - PullRequest
0 голосов
/ 06 мая 2019

Контекст

У меня есть конечная точка API api/v1/checkin/, которая возвращает текущие DeviceGroup и AppVersions для App, который должен быть активным.

Проблема

Конечная точка в настоящее время возвращает данные вместе с правильно отфильтрованным AppVersions следующим образом:

{
    "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"
        ]
    }
}

Цель

Я хочу, чтобы app_versions в ответе содержало больше данных, напримерэто:

{
    "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.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}
    }

Я предполагаю, что мне нужно изменить get_app_versions(), чтобы достичь своей цели, но я понятия не имею, как.

Что я должен изменить, чтобы получить желаемый ответ?

РЕДАКТИРОВАТЬ

Метод get_current_app_versions, который выполняет фильтрацию

# 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 Ответ

2 голосов
/ 06 мая 2019

Вы правы, предполагая, что вам придется изменить get_app_versions, и вместо возврата списка в строке return [o.app_version_name for o in qs] вам нужно будет вернуть список словарей.

Вам потребуется создать полный сериализатор для модели AppVersions.и затем в вашей get_app_versions правильной сериализации вы возвращаете значения, передавая их в ваш новый сериализатор, который содержит все поля, которые вы хотели бы вернуть return AppVersionSerializer2(qs, many=True).data.

Возможно, вам придется переопределить сериализацию определенных полей, так как они не могут обрабатываться сериализатором автоматически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...