Как использовать 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
и поле пола не существует.