Как использовать ModelSerializer и поле serializer в ModelSerializer?

serializer

# serialize
serializer = GetDealsResponseSerializer(
    data={
        "deals": [model_to_dict(deal) for deal in deals],
        "is_remained": is_remained,
    }
)

serializer.is_valid(raise_exception=True)


# serializers
class DealSerializer(serializers.ModelSerializer):
    area_for_exclusive_use_pyung = serializers.SerializerMethodField(
        "convert_square_meter_to_pyung"
    )
    area_for_exclusive_use_price_per_pyung = serializers.SerializerMethodField(
        "calc_price_per_pyung"
    )
    is_deal_canceled = serializers.SerializerMethodField("calc_is_deal_canceled")
    floor = serializers.SerializerMethodField("stringify_floor")

    def __init__(self, instance=None, data=..., **kwargs):
        super().__init__(instance, data, **kwargs)
        self.area_for_exclusive_use_pyung = None

    class Meta:
        model = Deal
        fields = (
            "id",
            "deal_price",
            "brokerage_type",
            "deal_year",
            "land_area",
            "deal_month",
            "deal_day",
            "area_for_exclusive_use",
            "floor",
            "is_deal_canceled",
            "deal_canceled_date",
            "area_for_exclusive_use_pyung",
            "area_for_exclusive_use_price_per_pyung",
            "deal_type",
            "real_estate_id",
        )

    def convert_square_meter_to_pyung(self, instance) -> Decimal:
        self.pyung = round(
            Decimal(instance.area_for_exclusive_use) / Decimal(3.305785), 2
        )
        return self.pyung

    def calc_price_per_pyung(self, instance) -> Decimal:
        return round(instance.deal_price / self.pyung, 2)

    def calc_is_deal_canceled(self, instance) -> bool:
        if instance.is_deal_canceled == "O":
            return True
        return False

    def stringify_floor(self, instance) -> str:
        self.floor = str(instance.floor)
        return self.floor



class GetDealsResponseSerializer(DealSerializer):
    deals = DealSerializer(many=True)
    is_remained = serializers.BooleanField(required=False)

    class Meta:
        model = Deal
        fields = (
            "id",
            "deal_price",
            "brokerage_type",
            "deal_year",
            "land_area",
            "deal_month",
            "deal_day",
            "area_for_exclusive_use",
            "floor",
            "is_deal_canceled",
            "deal_canceled_date",
            "area_for_exclusive_use_pyung",
            "area_for_exclusive_use_price_per_pyung",
            "deal_type",
            "real_estate_id",
            "deals",
        )

Ошибка

rest_framework.exceptions.ValidationError: {'deal_price': [ErrorDetail(string='This field is required.', code='required')], 'deal_year': [ErrorDetail(string='This field is required.', code='required')], 'land_area': [ErrorDetail(string='This field is required.', code='required')], 'deal_month': [ErrorDetail(string='This field is required.', code='required')], 'deal_day': [ErrorDetail(string='This field is required.', code='required')], 'area_for_exclusive_use': [ErrorDetail(string='This field is required.', code='required')], 'deal_type': [ErrorDetail(string='This field is required.', code='required')]}

Схема для документов

@extend_schema(
responses={
    200: PolymorphicProxySerializer(
        component_name="Deals",
        serializers=[GetDealsResponseSerializer],
        resource_type_field_name=None,
    ),
    400: OpenApiResponse(description="bad request"),
    404: OpenApiResponse(description="not found"),
},)

Я хочу использовать сериализатор для ответа и документов. Если я просто использую DealSerializer для сделок, то все работает хорошо. Мне нужен дополнительный ключ is_remained. Поэтому я добавил поле is_remained в GetDealsResponseSerializer. Но я не могу использовать SerializerMethodFields DealSerializer'а

Я пробовал вызывать super().__init__() в GetDealsResponseSerializer и не нашел решения.

Как я могу использовать этот стиль?

Другой подход -

class IsRemainedSerializer(serializers.Serializer):
    is_remained = serializers.BooleanField(required=False)


class GetDealsResponseSerializer(serializers.Serializer):
    deals = DealSerializer(many=True)
    is_remained = IsRemainedSerializer()

    class Meta:
        model = Deal
        fields = (
            "id",
            "deal_price",
            "brokerage_type",
            "deal_year",
            "land_area",
            "deal_month",
            "deal_day",
            "area_for_exclusive_use",
            "floor",
            "is_deal_canceled",
            "deal_canceled_date",
            "area_for_exclusive_use_pyung",
            "area_for_exclusive_use_price_per_pyung",
            "deal_type",
            "real_estate_id",
            "deals",
            "is_remained",
        )

        validated_deals = DealSerializer(deals, many=True).data
        validated_is_remained = IsRemainedSerializer({"is_remained": is_remained}).data

        data = {
            "deals": validated_deals,
            "is_remained": validated_is_remained,
        }

        serializer = GetDealsResponseSerializer(data=data)

        serializer.is_valid(raise_exception=True)

        serializer.validated_data

Я проверил serializer.validated_data и поле пола не существует.

Вернуться на верх