| Server IP : 85.214.239.14 / Your IP : 216.73.216.178 Web Server : Apache/2.4.65 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 8.2.29 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/3/task/3/cwd/srv/modoboa/env/lib/python3.5/site-packages/rest_framework_nested/ |
Upload File : |
"""
Serializer fields that deal with relationships with nested resources.
These fields allow you to specify the style that should be used to represent
model relationships with hyperlinks.
"""
from __future__ import unicode_literals
from functools import reduce # import reduce from functools for compatibility with python 3
import rest_framework.relations
# fix for basestring
try:
basestring
except NameError:
basestring = str
class NestedHyperlinkedRelatedField(rest_framework.relations.HyperlinkedRelatedField):
lookup_field = 'pk'
parent_lookup_kwargs = {
'parent_pk': 'parent__pk'
}
def __init__(self, *args, **kwargs):
self.parent_lookup_kwargs = kwargs.pop('parent_lookup_kwargs', self.parent_lookup_kwargs)
super(NestedHyperlinkedRelatedField, self).__init__(*args, **kwargs)
def get_url(self, obj, view_name, request, format):
"""
Given an object, return the URL that hyperlinks to the object.
May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
attributes are not configured to correctly match the URL conf.
"""
# Unsaved objects will not yet have a valid URL.
if hasattr(obj, 'pk') and obj.pk in (None, ''):
return None
# default lookup from rest_framework.relations.HyperlinkedRelatedField
lookup_value = getattr(obj, self.lookup_field)
kwargs = {self.lookup_url_kwarg: lookup_value}
# multi-level lookup
for parent_lookup_kwarg in list(self.parent_lookup_kwargs.keys()):
underscored_lookup = self.parent_lookup_kwargs[parent_lookup_kwarg]
# split each lookup by their __, e.g. "parent__pk" will be split into "parent" and "pk", or
# "parent__super__pk" would be split into "parent", "super" and "pk"
lookups = underscored_lookup.split('__')
# use the Django ORM to lookup this value, e.g., obj.parent.pk
lookup_value = reduce(getattr, [obj] + lookups)
# store the lookup_name and value in kwargs, which is later passed to the reverse method
kwargs.update({parent_lookup_kwarg: lookup_value})
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
def get_object(self, view_name, view_args, view_kwargs):
"""
Return the object corresponding to a matched URL.
Takes the matched URL conf arguments, and should return an
object instance, or raise an `ObjectDoesNotExist` exception.
"""
# default lookup from rest_framework.relations.HyperlinkedRelatedField
lookup_value = view_kwargs[self.lookup_url_kwarg]
kwargs = {self.lookup_url_kwarg: lookup_value}
# multi-level lookup
for parent_lookup_kwarg in list(self.parent_lookup_kwargs.keys()):
lookup_value = view_kwargs[parent_lookup_kwarg]
kwargs.update({self.parent_lookup_kwargs[parent_lookup_kwarg]: lookup_value})
return self.get_queryset().get(**kwargs)
def use_pk_only_optimization(self):
return False
class NestedHyperlinkedIdentityField(NestedHyperlinkedRelatedField):
def __init__(self, view_name=None, **kwargs):
assert view_name is not None, 'The `view_name` argument is required.'
kwargs['read_only'] = True
kwargs['source'] = '*'
super(NestedHyperlinkedIdentityField, self).__init__(view_name=view_name, **kwargs)