From bbe0cc58953d13defc4c7889a176e91dc542787a Mon Sep 17 00:00:00 2001
From: Sylvain Le Bon <sylvain@happy-dev.fr>
Date: Sun, 3 Jun 2018 16:06:28 +0200
Subject: [PATCH] update: nested fields can now be used for any type of
 relation

---
 djangoldp/serializers.py |  1 -
 djangoldp/views.py       | 23 ++++++++++++++++++++---
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py
index 19e7c2c0..0b081728 100644
--- a/djangoldp/serializers.py
+++ b/djangoldp/serializers.py
@@ -18,7 +18,6 @@ class JsonLdRelatedField(HyperlinkedRelatedField):
         #get the field name associated with the url of the view
         try:
             lookup_field = get_resolver().reverse_dict[self.view_name][0][0][1][0]
-            print(self.view_name, self.queryset, lookup_field)
             self.lookup_field = lookup_field
             self.lookup_url_kwarg = lookup_field
         except MultiValueDictKeyError:
diff --git a/djangoldp/views.py b/djangoldp/views.py
index d1cb4b8f..d894ebb6 100644
--- a/djangoldp/views.py
+++ b/djangoldp/views.py
@@ -2,6 +2,7 @@ from pyld import jsonld
 from django.apps import apps
 from django.conf import settings
 from django.conf.urls import url, include
+from django.core.exceptions import FieldDoesNotExist
 from django.core.urlresolvers import get_resolver
 from django.shortcuts import get_object_or_404
 from django.utils.decorators import classonlymethod
@@ -119,6 +120,7 @@ class LDPNestedViewSet(LDPViewSet):
     """A special case of LDPViewSet serving objects of a relation of a given object (e.g. members of a group, or skills of a user)"""
     parent_model = None
     parent_lookup_field = None
+    related_field = None
     nested_field = None
     nested_related_name = None
     
@@ -130,18 +132,33 @@ class LDPNestedViewSet(LDPViewSet):
         super().perform_create(serializer, **kwargs)
     
     def get_queryset(self, *args, **kwargs):
-        return getattr(self.get_parent(), self.nested_field).all()
+        if self.related_field.many_to_many or self.related_field.one_to_many:
+            return getattr(self.get_parent(), self.nested_field).all()
+        if self.related_field.many_to_one or self.related_field.one_to_one:
+            return [getattr(self.get_parent(), self.nested_field)]
+    
+    @classonlymethod
+    def get_related_fields(cls, model):
+        return {field.get_accessor_name():field for field in model._meta.fields_map.values()}
     
     @classonlymethod
     def nested_urls(cls, nested_field, **kwargs):
-        related_field = cls.get_model(**kwargs)._meta.get_field(nested_field)
+        try:
+            related_field = cls.get_model(**kwargs)._meta.get_field(nested_field)
+        except FieldDoesNotExist:
+            related_field = cls.get_related_fields(cls.get_model(**kwargs))[nested_field]
+        if related_field.related_query_name:
+            nested_related_name = related_field.related_query_name()
+        else:
+            nested_related_name = related_field.remote_field.attname
         
         return cls.urls(
             model = related_field.related_model,
             exclude = (),
             parent_model = cls.get_model(**kwargs),
             nested_field = nested_field,
-            nested_related_name = related_field.related_query_name(),
+            nested_related_name = nested_related_name,
+            related_field = related_field,
             parent_lookup_field = cls.get_lookup_arg(**kwargs),
             model_prefix = cls.get_model(**kwargs)._meta.object_name.lower(),
             lookup_url_kwarg = related_field.related_model._meta.object_name.lower()+'_id')
-- 
GitLab