Skip to content

Commit cd2521e

Browse files
Fix model field serializer with computed field (#1349)
Co-authored-by: Sydney Runkle <[email protected]>
1 parent 61318d9 commit cd2521e

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

src/serializers/computed_fields.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,12 @@ impl ComputedFields {
5252
// Do not serialize computed fields
5353
return Ok(());
5454
}
55-
for computed_fields in &self.0 {
56-
computed_fields.to_python(model, output_dict, filter, include, exclude, extra)?;
55+
for computed_field in &self.0 {
56+
let field_extra = Extra {
57+
field_name: Some(computed_field.property_name.as_str()),
58+
..*extra
59+
};
60+
computed_field.to_python(model, output_dict, filter, include, exclude, &field_extra)?;
5761
}
5862
Ok(())
5963
}
@@ -83,12 +87,16 @@ impl ComputedFields {
8387
if extra.exclude_none && value.is_none() {
8488
continue;
8589
}
90+
let field_extra = Extra {
91+
field_name: Some(computed_field.property_name.as_str()),
92+
..*extra
93+
};
8694
let cfs = ComputedFieldSerializer {
8795
model,
8896
computed_field,
8997
include: next_include.as_ref(),
9098
exclude: next_exclude.as_ref(),
91-
extra,
99+
extra: &field_extra,
92100
};
93101
let key = match extra.by_alias {
94102
true => computed_field.alias.as_str(),

tests/serializers/test_model.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,42 @@ def ser_x(self, v: Any, _) -> str:
565565
assert json.loads(s.to_json(Model(x=1000))) == {'x': '1_000'}
566566

567567

568+
def test_function_plain_field_serializer_with_computed_field():
569+
@dataclasses.dataclass
570+
class Model:
571+
x: int
572+
573+
@property
574+
def computed_field_x(self) -> int:
575+
return self.x + 200
576+
577+
def ser_func(self, v: Any, info: core_schema.FieldSerializationInfo) -> str:
578+
return info.field_name + '_' + str(v * 2)
579+
580+
field_str_with_field_serializer = core_schema.str_schema(
581+
serialization=core_schema.plain_serializer_function_ser_schema(
582+
Model.ser_func,
583+
is_field_serializer=True,
584+
info_arg=True,
585+
return_schema=core_schema.any_schema(),
586+
)
587+
)
588+
589+
s = SchemaSerializer(
590+
core_schema.model_schema(
591+
Model,
592+
core_schema.model_fields_schema(
593+
{'x': core_schema.model_field(field_str_with_field_serializer)},
594+
computed_fields=[
595+
core_schema.computed_field('computed_field_x', field_str_with_field_serializer),
596+
],
597+
),
598+
)
599+
)
600+
assert json.loads(s.to_json(Model(x=1000))) == {'x': 'x_2000', 'computed_field_x': 'computed_field_x_2400'}
601+
assert s.to_python(Model(x=2000)) == {'x': 'x_4000', 'computed_field_x': 'computed_field_x_4400'}
602+
603+
568604
def test_function_wrap_field_serializer_to_json():
569605
@dataclasses.dataclass
570606
class Model:

0 commit comments

Comments
 (0)