mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-12-04 16:54:02 +03:00
Merge ec86abe3eb into 442444f0be
This commit is contained in:
commit
b7538dba81
|
|
@ -6,8 +6,8 @@ source:
|
|||
# Serializers
|
||||
|
||||
> Expanding the usefulness of the serializers is something that we would
|
||||
like to address. However, it's not a trivial problem, and it
|
||||
will take some serious design work.
|
||||
> like to address. However, it's not a trivial problem, and it
|
||||
> will take some serious design work.
|
||||
>
|
||||
> — Russell Keith-Magee, [Django users group][cite]
|
||||
|
||||
|
|
@ -325,10 +325,10 @@ The following example demonstrates how you might handle creating a user with a n
|
|||
|
||||
For updates you'll want to think carefully about how to handle updates to relationships. For example if the data for the relationship is `None`, or not provided, which of the following should occur?
|
||||
|
||||
* Set the relationship to `NULL` in the database.
|
||||
* Delete the associated instance.
|
||||
* Ignore the data and leave the instance as it is.
|
||||
* Raise a validation error.
|
||||
- Set the relationship to `NULL` in the database.
|
||||
- Delete the associated instance.
|
||||
- Ignore the data and leave the instance as it is.
|
||||
- Raise a validation error.
|
||||
|
||||
Here's an example for an `.update()` method on our previous `UserSerializer` class.
|
||||
|
||||
|
|
@ -434,9 +434,9 @@ The `ModelSerializer` class provides a shortcut that lets you automatically crea
|
|||
|
||||
**The `ModelSerializer` class is the same as a regular `Serializer` class, except that**:
|
||||
|
||||
* It will automatically generate a set of fields for you, based on the model.
|
||||
* It will automatically generate validators for the serializer, such as unique_together validators.
|
||||
* It includes simple default implementations of `.create()` and `.update()`.
|
||||
- It will automatically generate a set of fields for you, based on the model.
|
||||
- It will automatically generate validators for the serializer, such as unique_together validators.
|
||||
- It includes simple default implementations of `.create()` and `.update()`.
|
||||
|
||||
Declaring a `ModelSerializer` looks like this:
|
||||
|
||||
|
|
@ -556,7 +556,6 @@ Please review the [Validators Documentation](/api-guide/validators/) for details
|
|||
|
||||
---
|
||||
|
||||
|
||||
## Additional keyword arguments
|
||||
|
||||
There is also a shortcut allowing you to specify arbitrary additional keyword arguments on fields, using the `extra_kwargs` option. As in the case of `read_only_fields`, this means you do not need to explicitly declare the field on the serializer.
|
||||
|
|
@ -694,7 +693,7 @@ Rather than relative URLs, such as:
|
|||
|
||||
/accounts/1/
|
||||
|
||||
If you *do* want to use relative URLs, you should explicitly pass `{'request': None}`
|
||||
If you _do_ want to use relative URLs, you should explicitly pass `{'request': None}`
|
||||
in the serializer context.
|
||||
|
||||
## How hyperlinked views are determined
|
||||
|
|
@ -746,7 +745,7 @@ The name of the URL field defaults to 'url'. You can override this globally, by
|
|||
|
||||
# ListSerializer
|
||||
|
||||
The `ListSerializer` class provides the behavior for serializing and validating multiple objects at once. You won't *typically* need to use `ListSerializer` directly, but should instead simply pass `many=True` when instantiating a serializer.
|
||||
The `ListSerializer` class provides the behavior for serializing and validating multiple objects at once. You won't _typically_ need to use `ListSerializer` directly, but should instead simply pass `many=True` when instantiating a serializer.
|
||||
|
||||
When a serializer is instantiated and `many=True` is passed, a `ListSerializer` instance will be created. The serializer class then becomes a child of the parent `ListSerializer`
|
||||
|
||||
|
|
@ -766,10 +765,10 @@ This is `None` by default, but can be set to a positive integer if you want to v
|
|||
|
||||
### Customizing `ListSerializer` behavior
|
||||
|
||||
There *are* a few use cases when you might want to customize the `ListSerializer` behavior. For example:
|
||||
There _are_ a few use cases when you might want to customize the `ListSerializer` behavior. For example:
|
||||
|
||||
* You want to provide particular validation of the lists, such as checking that one element does not conflict with another element in a list.
|
||||
* You want to customize the create or update behavior of multiple objects.
|
||||
- You want to provide particular validation of the lists, such as checking that one element does not conflict with another element in a list.
|
||||
- You want to customize the create or update behavior of multiple objects.
|
||||
|
||||
For these cases you can modify the class that is used when `many=True` is passed, by using the `list_serializer_class` option on the serializer `Meta` class.
|
||||
|
||||
|
|
@ -805,10 +804,10 @@ By default the `ListSerializer` class does not support multiple updates. This is
|
|||
|
||||
To support multiple updates you'll need to do so explicitly. When writing your multiple update code make sure to keep the following in mind:
|
||||
|
||||
* How do you determine which instance should be updated for each item in the list of data?
|
||||
* How should insertions be handled? Are they invalid, or do they create new objects?
|
||||
* How should removals be handled? Do they imply object deletion, or removing a relationship? Should they be silently ignored, or are they invalid?
|
||||
* How should ordering be handled? Does changing the position of two items imply any state change or is it ignored?
|
||||
- How do you determine which instance should be updated for each item in the list of data?
|
||||
- How should insertions be handled? Are they invalid, or do they create new objects?
|
||||
- How should removals be handled? Do they imply object deletion, or removing a relationship? Should they be silently ignored, or are they invalid?
|
||||
- How should ordering be handled? Does changing the position of two items imply any state change or is it ignored?
|
||||
|
||||
You will need to add an explicit `id` field to the instance serializer. The default implicitly-generated `id` field is marked as `read_only`. This causes it to be removed on updates. Once you declare it explicitly, it will be available in the list serializer's `update` method.
|
||||
|
||||
|
|
@ -868,17 +867,17 @@ Occasionally you might need to explicitly specify how the child and parent class
|
|||
|
||||
This class implements the same basic API as the `Serializer` class:
|
||||
|
||||
* `.data` - Returns the outgoing primitive representation.
|
||||
* `.is_valid()` - Deserializes and validates incoming data.
|
||||
* `.validated_data` - Returns the validated incoming data.
|
||||
* `.errors` - Returns any errors during validation.
|
||||
* `.save()` - Persists the validated data into an object instance.
|
||||
- `.data` - Returns the outgoing primitive representation.
|
||||
- `.is_valid()` - Deserializes and validates incoming data.
|
||||
- `.validated_data` - Returns the validated incoming data.
|
||||
- `.errors` - Returns any errors during validation.
|
||||
- `.save()` - Persists the validated data into an object instance.
|
||||
|
||||
There are four methods that can be overridden, depending on what functionality you want the serializer class to support:
|
||||
|
||||
* `.to_representation()` - Override this to support serialization, for read operations.
|
||||
* `.to_internal_value()` - Override this to support deserialization, for write operations.
|
||||
* `.create()` and `.update()` - Override either or both of these to support saving instances.
|
||||
- `.to_representation()` - Override this to support serialization, for read operations.
|
||||
- `.to_internal_value()` - Override this to support deserialization, for write operations.
|
||||
- `.create()` and `.update()` - Override either or both of these to support saving instances.
|
||||
|
||||
Because this class provides the same interface as the `Serializer` class, you can use it with the existing generic class-based views exactly as you would for a regular `Serializer` or `ModelSerializer`.
|
||||
|
||||
|
|
@ -1013,9 +1012,9 @@ If you need to alter the serialization or deserialization behavior of a serializ
|
|||
|
||||
Some reasons this might be useful include...
|
||||
|
||||
* Adding new behavior for new serializer base classes.
|
||||
* Modifying the behavior slightly for an existing class.
|
||||
* Improving serialization performance for a frequently accessed API endpoint that returns lots of data.
|
||||
- Adding new behavior for new serializer base classes.
|
||||
- Modifying the behavior slightly for an existing class.
|
||||
- Improving serialization performance for a frequently accessed API endpoint that returns lots of data.
|
||||
|
||||
The signatures for these methods are as follows:
|
||||
|
||||
|
|
@ -1031,7 +1030,7 @@ May be overridden in order to modify the representation style. For example:
|
|||
ret['username'] = ret['username'].lower()
|
||||
return ret
|
||||
|
||||
#### ``to_internal_value(self, data)``
|
||||
#### `to_internal_value(self, data)`
|
||||
|
||||
Takes the unvalidated incoming data as input and should return the validated data that will be made available as `serializer.validated_data`. The return value will also be passed to the `.create()` or `.update()` methods if `.save()` is called on the serializer class.
|
||||
|
||||
|
|
@ -1058,12 +1057,12 @@ Like Django's `Model` and `ModelForm` classes, the inner `Meta` class on seriali
|
|||
class Meta(MyBaseSerializer.Meta):
|
||||
model = Account
|
||||
|
||||
Typically we would recommend *not* using inheritance on inner Meta classes, but instead declaring all options explicitly.
|
||||
Typically we would recommend _not_ using inheritance on inner Meta classes, but instead declaring all options explicitly.
|
||||
|
||||
Additionally, the following caveats apply to serializer inheritance:
|
||||
|
||||
* Normal Python name resolution rules apply. If you have multiple base classes that declare a `Meta` inner class, only the first one will be used. This means the child’s `Meta`, if it exists, otherwise the `Meta` of the first parent, etc.
|
||||
* It’s possible to declaratively remove a `Field` inherited from a parent class by setting the name to be `None` on the subclass.
|
||||
- Normal Python name resolution rules apply. If you have multiple base classes that declare a `Meta` inner class, only the first one will be used. This means the child’s `Meta`, if it exists, otherwise the `Meta` of the first parent, etc.
|
||||
- It’s possible to declaratively remove a `Field` inherited from a parent class by setting the name to be `None` on the subclass.
|
||||
|
||||
class MyBaseSerializer(ModelSerializer):
|
||||
my_field = serializers.CharField()
|
||||
|
|
@ -1193,7 +1192,6 @@ The [drf-encrypt-content][drf-encrypt-content] package helps you encrypt your da
|
|||
|
||||
The [drf-shapeless-serializers][drf-shapeless-serializers] package provides dynamic serializer configuration capabilities, allowing runtime field selection, renaming, attribute modification, and nested relationship configuration without creating multiple serializer classes. It helps eliminate serializer boilerplate while providing flexible API responses.
|
||||
|
||||
|
||||
[cite]: https://groups.google.com/d/topic/django-users/sVFaOfQi4wY/discussion
|
||||
[relations]: relations.md
|
||||
[model-managers]: https://docs.djangoproject.com/en/stable/topics/db/managers/
|
||||
|
|
@ -1217,3 +1215,8 @@ The [drf-shapeless-serializers][drf-shapeless-serializers] package provides dyna
|
|||
[drf-writable-nested]: https://github.com/beda-software/drf-writable-nested
|
||||
[drf-encrypt-content]: https://github.com/oguzhancelikarslan/drf-encrypt-content
|
||||
[drf-shapeless-serializers]: https://github.com/khaledsukkar2/drf-shapeless-serializers
|
||||
|
||||
> **Note**: The Browsable API internally simulates a `POST` request in order to
|
||||
> determine the serializer fields for its HTML form. Because of this,
|
||||
> `get_serializer_class()` or permission checks may observe `request.method`
|
||||
> as `"POST"` even during GET requests. This is expected behaviour.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user