def get_object(self):
"""
Incase the lookup is on an object that has been hyperlinked
then update the queryset filter appropriately
"""
if self.kwargs.get(self.lookup_field, None) is None:
raise ParseError(
'Expected URL keyword argument `%s`.' % self.lookup_field
)
queryset = self.filter_queryset(self.get_queryset())
filter_kwargs = {}
serializer = self.get_serializer()
lookup_field = self.lookup_field
if self.lookup_field in serializer.get_fields():
k = serializer.get_fields()[self.lookup_field]
if isinstance(k, serializers.HyperlinkedRelatedField):
lookup_field = '%s__%s' % (self.lookup_field, k.lookup_field)
filter_kwargs[lookup_field] = self.kwargs[self.lookup_field]
obj = get_object_or_404(queryset, **filter_kwargs)
# May raise a permission denied
self.check_object_permissions(self.request, obj)
return obj
python类HyperlinkedRelatedField()的实例源码
def pre_save(self, obj):
"""
Set any attributes on the object that are implicit in the request.
"""
# pk and/or slug attributes are implicit in the URL.
lookup = self.kwargs.get(self.lookup_field, None)
pk = self.kwargs.get(self.pk_url_kwarg, None)
slug = self.kwargs.get(self.slug_url_kwarg, None)
slug_field = slug and self.slug_field or None
if lookup:
serializer = self.get_serializer()
k = serializer.get_fields()[self.lookup_field]
queryset = self.get_queryset()
queryset = self.filter_queryset(queryset)
if isinstance(k, serializers.HyperlinkedRelatedField):
filter = {}
lookup_field = '%s__%s' % (self.lookup_field, k.lookup_field)
filter[lookup_field] = lookup
k_obj = get_object_or_404(queryset, **filter)
lookup = getattr(k_obj, self.lookup_field)
setattr(obj, self.lookup_field, lookup)
if pk:
setattr(obj, 'pk', pk)
if slug:
setattr(obj, slug_field, slug)
# Ensure we clean the attributes so that we don't eg return integer
# pk using a string representation, as provided by the url conf kwarg.
if hasattr(obj, 'full_clean'):
exclude = mixins._get_validation_exclusions(
obj, pk, slug_field, self.lookup_field)
obj.full_clean(exclude)
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
filter_kwargs = {}
serializer = self.get_serializer()
lookup_fields = getattr(self, 'lookup_fields', [])
for field in lookup_fields:
lookup_field = field
if lookup_field in serializer.get_fields():
k = serializer.get_fields()[lookup_field]
if isinstance(k, serializers.HyperlinkedRelatedField):
if k.source:
lookup_field = k.source
lookup_field = '%s__%s' % (lookup_field, k.lookup_field)
if self.kwargs.get(field, None) is None:
raise ParseError(
'Expected URL keyword argument `%s`.' % field
)
filter_kwargs[lookup_field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter_kwargs)
# May raise a permission denied
self.check_object_permissions(self.request, obj)
return obj
def _get_related_fields(self, fields, id_field):
return [k for (k, v) in fields
if k != id_field
and (isinstance(v, HyperlinkedRelatedField)
or isinstance(v, HyperlinkedIdentityField)
or isinstance(v, ItemLinkField)
or (isinstance(v, ManyRelatedField)
and isinstance(v.child_relation, HyperlinkedRelatedField)))]
def get_object(self, queryset=None):
"""Lookup user profile by pk or username"""
if self.kwargs.get(self.lookup_field, None) is None:
raise ParseError(
'Expected URL keyword argument `%s`.' % self.lookup_field
)
if queryset is None:
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer()
lookup_field = self.lookup_field
if self.lookup_field in serializer.get_fields():
k = serializer.get_fields()[self.lookup_field]
if isinstance(k, serializers.HyperlinkedRelatedField):
lookup_field = '%s__%s' % (self.lookup_field, k.lookup_field)
lookup = self.kwargs[self.lookup_field]
filter_kwargs = {lookup_field: lookup}
try:
pk = int(lookup)
except (TypeError, ValueError):
pass
else:
filter_kwargs = {'user__pk': pk}
obj = get_object_or_404(queryset, **filter_kwargs)
# May raise a permission denied
self.check_object_permissions(self.request, obj)
return obj
def get_object(self, queryset=None):
"""
Incase the lookup is on an object that has been hyperlinked
then update the queryset filter appropriately
"""
if self.kwargs.get(self.lookup_field, None) is None:
raise ParseError(
'Expected URL keyword argument `%s`.' % self.lookup_field
)
if queryset is None:
queryset = self.filter_queryset(self.get_queryset())
filter_kwargs = {}
serializer = self.get_serializer()
lookup_field = self.lookup_field
if self.lookup_field in serializer.get_fields():
k = serializer.get_fields()[self.lookup_field]
if isinstance(k, serializers.HyperlinkedRelatedField):
lookup_field = '%s__%s' % (self.lookup_field, k.lookup_field)
filter_kwargs[lookup_field] = self.kwargs[self.lookup_field]
obj = get_object_or_404(queryset, **filter_kwargs)
# May raise a permission denied
self.check_object_permissions(self.request, obj)
return obj
def pre_save(self, obj):
"""
Set any attributes on the object that are implicit in the request.
"""
# pk and/or slug attributes are implicit in the URL.
lookup = self.kwargs.get(self.lookup_field, None)
pk = self.kwargs.get(self.pk_url_kwarg, None)
slug = self.kwargs.get(self.slug_url_kwarg, None)
slug_field = slug and self.slug_field or None
if lookup:
serializer = self.get_serializer()
k = serializer.get_fields()[self.lookup_field]
queryset = self.get_queryset()
queryset = self.filter_queryset(queryset)
if isinstance(k, serializers.HyperlinkedRelatedField):
filter = {}
lookup_field = '%s__%s' % (self.lookup_field, k.lookup_field)
filter[lookup_field] = lookup
k_obj = get_object_or_404(queryset, **filter)
lookup = getattr(k_obj, self.lookup_field)
setattr(obj, self.lookup_field, lookup)
if pk:
setattr(obj, 'pk', pk)
if slug:
setattr(obj, slug_field, slug)
# Ensure we clean the attributes so that we don't eg return integer
# pk using a string representation, as provided by the url conf kwarg.
if hasattr(obj, 'full_clean'):
exclude = mixins._get_validation_exclusions(
obj, pk, slug_field, self.lookup_field)
obj.full_clean(exclude)
def get_object(self, queryset=None):
if queryset is None:
queryset = self.filter_queryset(self.get_queryset())
filter_kwargs = {}
serializer = self.get_serializer()
lookup_fields = getattr(self, 'lookup_fields', [])
for field in lookup_fields:
lookup_field = field
if lookup_field in serializer.get_fields():
k = serializer.get_fields()[lookup_field]
if isinstance(k, serializers.HyperlinkedRelatedField):
if k.source:
lookup_field = k.source
lookup_field = '%s__%s' % (lookup_field, k.lookup_field)
if self.kwargs.get(field, None) is None:
raise ParseError(
'Expected URL keyword argument `%s`.' % field
)
filter_kwargs[lookup_field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter_kwargs)
# May raise a permission denied
self.check_object_permissions(self.request, obj)
return obj
def to_internal_value(self, data):
""" TODO - I've had to copy this method from HyperlinkedRelatedField purely
so that it can deal with polymorphic models. This probably is not ideal.
"""
try:
http_prefix = data.startswith(('http:', 'https:'))
except AttributeError:
self.fail('incorrect_type', data_type=type(data).__name__)
if http_prefix:
# If needed convert absolute URLs to relative path
data = urlparse.urlparse(data).path
prefix = get_script_prefix()
if data.startswith(prefix):
data = '/' + data[len(prefix):]
try:
match = resolve(data)
except Resolver404:
self.fail('no_match')
if self._serializer_is_polymorphic:
# TODO - This is not really what we want. Need to make sure
# that match.view_name points to a view which uses a subtype
# serializer for this polymorphic serializer
self.view_name = match.view_name
if match.view_name != self.view_name:
self.fail('incorrect_match')
try:
return self.get_object(match.view_name, match.args, match.kwargs)
except (ObjectDoesNotExist, TypeError, ValueError):
self.fail('does_not_exist')