Chapter 7 — Forms + serializer
6 tests covering ModelFormFor<T> parse/from_json/error aggregation/
bound-validation/null handling/insert-query emission. No DB needed.
Run with cargo test --test cookbook_chapter07_forms.
The forms core, the serializer derive, and each serializer extension (nested / method / many / validators / ViewSet wiring) all ship with passing tests:
$ cargo test --test cookbook_chapter07_forms \
--test cookbook_chapter07b_serializer \
--test cookbook_chapter07f_serializer_method_and_validators \
--test cookbook_chapter07g_nested_serializer \
--test cookbook_chapter07h_many_serializer
cookbook_chapter07_forms .................................. ok (6)
cookbook_chapter07b_serializer ............................ ok (6)
cookbook_chapter07f_serializer_method_and_validators ...... ok (4)
cookbook_chapter07g_nested_serializer ..................... ok (4)
cookbook_chapter07h_many_serializer ....................... ok (4)
- §7.95
ModelFormFor::<T>::parse(&HashMap<String,String>)— form- encoded payload →(columns, values)with per-field bound validation. Auto PK andauto_now_addcolumns are skipped (DB fills them). →modelform_parses_form_encoded_into_typed_values - §7.95 missing required fields aggregate into
FormErrors, one entry per field. →modelform_missing_required_fields_aggregate_errors - §7.96
ModelFormFor::<T>::from_json(&serde_json::Value)— JSON request body. Null values onOption<T>write explicitSqlValue::Null. →modelform_from_json_parses_object,modelform_from_json_null_writes_explicit_null - §7.98
min/maxbounds run at parse time. Out-of-range values land inFormErrorskeyed by field. →modelform_bound_violation_lands_in_form_errors - §7.99
into_insert_query()emits anInsertQueryagainst the model's table. →modelform_into_insert_query_targets_model_table
Note:
ModelFormFor::parseskips every auto-populated field —auto_now_addtimestamps likejoined_at: Auto<DateTime<Utc>>andAuto<T>primary keys — because the database fills them on INSERT. Your form only has to carry the fields a user actually enters.
7.99b #[derive(Serializer)] — DRF-shape JSON façade
6 tests in tests/cookbook_chapter07b_serializer.rs exercise the
serializer derive against the cookbook's Author model. Run with
cargo test --test cookbook_chapter07b_serializer.
from_model+to_valueround-trip — every field maps from the model and lands in the JSON output. →serializer_from_model_then_to_value_round_trip#[serializer(read_only)]— excluded fromwritable_fields(), still appears in JSON output. →read_only_field_omitted_from_writable_fields#[serializer(write_only)]— excluded from JSON output, accepted on input. →write_only_field_excluded_from_json_output#[serializer(source = "x")]— renames the JSON key to a different model field. →source_attribute_renames_json_key#[serializer(skip)]— usesDefault::default(), leaves the field in JSON but excludes it fromwritable_fields(). →skip_field_uses_default_and_appears_in_json_unchangedmany_to_value— batches aVec<Model>into a JSON array. →many_to_value_batches_into_json_array
Beyond the core derive, #[derive(Serializer)] also supports:
- Nested FK —
#[serializer(nested)]on a field whose type is itself a serializer and whose model source is aForeignKey<Parent>emits the nesting glue. The FK must be loaded first (.get(&pool)or.select_related(...)). →tests/cookbook_chapter07g_nested_serializer.rs - Computed fields —
#[serializer(method = "fn_name")]calls an inherentfn(model: &T) -> FieldTypeduringfrom_model. →tests/cookbook_chapter07f_serializer_method_and_validators.rs - ViewSet ↔ Serializer wiring —
ViewSet::for_model(...).serializer::<S>()runs list/detail output through the serializer instead of the bare model. →tests/cookbook_chapter09b_viewset_serializer.rs - Collections (M2M / one-to-many) —
#[serializer(many = ChildSerializer)]emits a typedset_<field>(&mut self, &[ChildModel])setter; fetch the children (accessors are async), call the setter, then serialize. →tests/cookbook_chapter07h_many_serializer.rs - Per-field validators —
#[serializer(validate = "fn_name")]runs a per-field validator, on top of model-levelmin/max/max_length. →tests/cookbook_chapter07f_serializer_method_and_validators.rs