Skip to content

Commit 0f508c5

Browse files
committed
Docs for advanced default argument usage. Closes #1945
1 parent d2537e5 commit 0f508c5

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

docs/api-guide/validators.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,38 @@ If you want the date field to be entirely hidden from the user, then use `Hidden
156156

157157
---
158158

159+
# Advanced 'default' argument usage
160+
161+
Validators that are applied across multiple fields in the serializer can sometimes require a field input that should not be provided by the API client, but that *is* available as input to the validator.
162+
163+
Two patterns that you may want to use for this sort of validation include:
164+
165+
* Using `HiddenField`. This field will be present in `validated_data` but *will not* be used in the serializer output representation.
166+
* Using a standard field with `read_only=True`, but that also includes a `default=…` argument. This field *will* be used in the serializer output representation, but cannot be set directly by the user.
167+
168+
REST framework includes a couple of defaults that may be useful in this context.
169+
170+
#### CurrentUserDefault
171+
172+
A default class that can be used to represent the current user. In order to use this, the 'request' must have been provided as part of the context dictionary when instantiating the serializer.
173+
174+
owner = serializers.HiddenField(
175+
default=CurrentUserDefault()
176+
)
177+
178+
#### CreateOnlyDefault
179+
180+
A default class that can be used to *only set a default argument during create operations*. During updates the field is omitted.
181+
182+
It takes a single argument, which is the default value or callable that should be used during create operations.
183+
184+
created_at = serializers.DateTimeField(
185+
read_only=True,
186+
default=CreateOnlyDefault(timezone.now)
187+
)
188+
189+
---
190+
159191
# Writing custom validators
160192

161193
You can use any of Django's existing validators, or write your own custom validators.

rest_framework/fields.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ def __repr__(self):
117117
return '%s(%s)' % (self.__class__.__name__, repr(self.default))
118118

119119

120+
class CurrentUserDefault:
121+
def set_context(self, serializer_field):
122+
self.user = serializer_field.context['request'].user
123+
124+
def __call__(self):
125+
return self.user
126+
127+
def __repr__(self):
128+
return '%s()' % self.__class__.__name__
129+
130+
120131
class SkipField(Exception):
121132
pass
122133

0 commit comments

Comments
 (0)