mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-25 19:14:01 +03:00
Merge pull request #3605 from ryanhiebert/slug-related-field-queryset
RelatedField get_queryset and context
This commit is contained in:
commit
f1b28b4d63
|
@ -330,6 +330,8 @@ To implement a custom relational field, you should override `RelatedField`, and
|
|||
|
||||
If you want to implement a read-write relational field, you must also implement the `.to_internal_value(self, data)` method.
|
||||
|
||||
To provide a dynamic queryset based on the `context`, you can also override `.get_queryset(self)` instead of specifying `.queryset` on the class or when initializing the field.
|
||||
|
||||
## Example
|
||||
|
||||
For example, we could define a relational field to serialize a track to a custom string representation, using its ordering, title, and duration.
|
||||
|
|
|
@ -21,6 +21,15 @@ from rest_framework.reverse import reverse
|
|||
from rest_framework.utils import html
|
||||
|
||||
|
||||
def method_overridden(method_name, klass, instance):
|
||||
"""
|
||||
Determine if a method has been overridden.
|
||||
"""
|
||||
method = getattr(klass, method_name)
|
||||
default_method = getattr(method, '__func__', method) # Python 3 compat
|
||||
return default_method is not getattr(instance, method_name).__func__
|
||||
|
||||
|
||||
class Hyperlink(six.text_type):
|
||||
"""
|
||||
A string like object that additionally has an associated name.
|
||||
|
@ -65,10 +74,12 @@ class RelatedField(Field):
|
|||
self.queryset = kwargs.pop('queryset', self.queryset)
|
||||
self.html_cutoff = kwargs.pop('html_cutoff', self.html_cutoff)
|
||||
self.html_cutoff_text = kwargs.pop('html_cutoff_text', self.html_cutoff_text)
|
||||
assert self.queryset is not None or kwargs.get('read_only', None), (
|
||||
'Relational field must provide a `queryset` argument, '
|
||||
'or set read_only=`True`.'
|
||||
)
|
||||
|
||||
if not method_overridden('get_queryset', RelatedField, self):
|
||||
assert self.queryset is not None or kwargs.get('read_only', None), (
|
||||
'Relational field must provide a `queryset` argument, '
|
||||
'override `get_queryset`, or set read_only=`True`.'
|
||||
)
|
||||
assert not (self.queryset is not None and kwargs.get('read_only', None)), (
|
||||
'Relational fields should not provide a `queryset` argument, '
|
||||
'when setting read_only=`True`.'
|
||||
|
|
|
@ -176,6 +176,14 @@ class TestSlugRelatedField(APISimpleTestCase):
|
|||
representation = self.field.to_representation(self.instance)
|
||||
assert representation == self.instance.name
|
||||
|
||||
def test_no_queryset_init(self):
|
||||
class NoQuerySetSlugRelatedField(serializers.SlugRelatedField):
|
||||
def get_queryset(this):
|
||||
return self.queryset
|
||||
|
||||
field = NoQuerySetSlugRelatedField(slug_field='name')
|
||||
field.to_internal_value(self.instance.name)
|
||||
|
||||
|
||||
class TestManyRelatedField(APISimpleTestCase):
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue
Block a user