drf-extensions
drf-extensions copied to clipboard
Nested Relations get_url patch
Привет, перепробовал кучу вещей в инете для nested drf routing, остановился на твоем пакете. У тебя отсутствует генератор полей-ссылок на nested-urls (у базового не хватает kwargs для reverse).
class HyperlinkedNestedIdentityField(HyperlinkedIdentityField):
def __init__(self, view_name=None, additional_reverse_kwargs={}, **kwargs):
self.additional_reverse_kwargs = additional_reverse_kwargs
super(HyperlinkedNestedIdentityField, self).__init__(view_name, **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 obj.pk is None:
return None
kwargs = {}
for k, v in self.additional_reverse_kwargs.iteritems():
kwargs[k] = getattr(obj, v, v)
kwargs.update({self.lookup_url_kwarg: getattr(obj, self.lookup_field)})
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
Пример использования:
class MealRecordSerializer(serializers.HyperlinkedModelSerializer):
url = HyperlinkedNestedIdentityField(view_name='mealrecord-detail', read_only=True,
additional_reverse_kwargs={"parent_lookup_user_id": "user_id"})
class Meta:
model = MealRecord
fields = ('id', 'url', 'user', 'date', 'time', 'title', 'calories_count')
great, that helped me a lot. The only thing I found is that only works for one level depth.
with that in mind I modified it a little bit so I could used like object1.object2.object3_id.
def get_url(self, obj, view_name, request, format):
if obj.pk is None:
return None
kwargs = {}
for k, v in self.additional_reverse_kwargs.iteritems():
args = v.split('.')
source = obj
for arg in args:
source = getattr(source, arg, arg)
kwargs[k] = source
kwargs.update({self.lookup_url_kwarg: getattr(obj, self.lookup_field)})
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
use example:
url = HyperlinkedNestedIdentityRelatedField(view_name='entity-department-role-people-detail',
additional_reverse_kwargs={
"parent_lookup_role__department__entity": "role.department.entity_id",
"parent_lookup_role__department": "role.department_id",
"parent_lookup_role": "role_id",
})
I think the idea for drf-extensions to support nested urls like /users/1/posts/1/ and /users/1/posts/ with out-of-the box serializer fields is great. Would rename additional_reverse_kwargs to something shorter though, like lookup_kwargs.
Agree, I keep it this way following the @alexmakeev pattern.
Also, I think HyperlinkedIdentityField is only for pointing to the object itself, so it should be HyperlinkedNestedRelatedField.
Agree also
I've had a go at having this fixed, taking the original patch and the recommendations above. What do you think about this? https://gist.github.com/gnarea/1a2bd805237400cb37ef
I'm using this in my own project, and seems to work just fine.
would love to see this in this project.