Fix partial update for the ListSerializer. by NewVadim · Pull Request #4222 · encode/django-rest-framework (original) (raw)
This commit make the update from DRF 3.5.3 to 3.6.3 fail with:
File "/lib/python3.5/site-packages/rest_framework/serials
self._fields[key] = value
File "/lib/python3.5/site-packages/rest_framework/utils/_
field.bind(field_name=key, parent=self.serializer)
File "/lib/python3.5/site-packages/rest_framework/seriald
self.partial = self.parent.partial
AttributeError: 'YourSerializer' object has no attribute 'partial'
Cause is an entry in YourSerializer that nests another serializer:
class YourGroupSerializer(ModelValidatorMixin, SecureSerializerMixin, serializers.HyperlinkedModelSerializer):
# Mostly used for SETTING
your_set = YourSerializer(many=True, read_only=True)
Which then fails on the SecureSerializerMixin that filters nested entries on allowed entrys for that user:
class SecureSerializerMixin(object):
"""
Filters the queryset for a related field to those items the user has permissions for.
Does work with all serializers, but in general on nested serializers you don't use the queryset method, so then it does not work.
IN THE SERIALIZER
Without this mixin, the browsable api would show all options, not only those of the user.
Also without this mixin, it would be possible to post (=create) a horse in another stable, etc.
"""
def filter_queryset(self, field, kwargs):
try:
request = kwargs['context']['request']
# Not only for GET requests, but also for posts filter!
if not kwargs['context'].get('do_not_filter_api', False): # disables uneccesary filtering of serializers for performance
self.fields.get(field).queryset = filter_queryset(request, self.fields.get(field).queryset)
except AttributeError:
pass
except KeyError:
# No context. For safety use empty queryset!
try:
self.fields.get(field).queryset = self.field.get(field).queryset.none()
except AttributeError:
pass
def __init__(self, *args, **kwargs):
for field in self.fields:
self.filter_queryset(field, kwargs)
super(SecureSerializerMixin, self).__init__(*args, **kwargs)
The SecureSerializerMixin fails on for field in self.fields
.