From fde2f2c80659ceb809f0f1b1fc081813197d96da Mon Sep 17 00:00:00 2001
From: Jean-Baptiste <bleme@pm.me>
Date: Fri, 6 Sep 2019 09:33:06 +0200
Subject: [PATCH] update: federated GET

---
 ...905_1542.py => 0002_auto_20190906_0642.py} | 11 +++++----
 djangoldp/models.py                           | 14 ++++++++---
 djangoldp/serializers.py                      | 23 +++++++++++++++----
 djangoldp/tests/tests_get.py                  |  3 +++
 djangoldp/tests/tests_sources.py              |  2 +-
 djangoldp/tests/tests_temp.py                 |  5 ----
 djangoldp/urls.py                             |  2 +-
 7 files changed, 40 insertions(+), 20 deletions(-)
 rename djangoldp/migrations/{0002_auto_20190905_1542.py => 0002_auto_20190906_0642.py} (60%)

diff --git a/djangoldp/migrations/0002_auto_20190905_1542.py b/djangoldp/migrations/0002_auto_20190906_0642.py
similarity index 60%
rename from djangoldp/migrations/0002_auto_20190905_1542.py
rename to djangoldp/migrations/0002_auto_20190906_0642.py
index ff3b2dc1..c68a1c51 100644
--- a/djangoldp/migrations/0002_auto_20190905_1542.py
+++ b/djangoldp/migrations/0002_auto_20190906_0642.py
@@ -1,8 +1,9 @@
 # -*- coding: utf-8 -*-
-# Generated by Django 1.11 on 2019-09-05 15:42
+# Generated by Django 1.11 on 2019-09-06 06:42
 from __future__ import unicode_literals
 
-from django.db import migrations, models
+from django.db import migrations
+import djangoldp.fields
 
 
 class Migration(migrations.Migration):
@@ -16,9 +17,9 @@ class Migration(migrations.Migration):
             model_name='ldpsource',
             name='container',
         ),
-        migrations.AlterField(
+        migrations.AddField(
             model_name='ldpsource',
-            name='id',
-            field=models.URLField(primary_key=True, serialize=False),
+            name='urlid',
+            field=djangoldp.fields.LDPUrlField(null=True, unique=True),
         ),
     ]
diff --git a/djangoldp/models.py b/djangoldp/models.py
index 73c1c17d..dcebce7a 100644
--- a/djangoldp/models.py
+++ b/djangoldp/models.py
@@ -5,6 +5,7 @@ from django.urls import get_resolver
 from django.utils.datastructures import MultiValueDict, MultiValueDictKeyError
 from django.utils.decorators import classonlymethod
 
+from djangoldp.fields import LDPUrlField
 from djangoldp.permissions import LDPPermissions
 
 User._meta.rdf_type = "foaf:user"
@@ -12,6 +13,7 @@ User._meta.owner_field = "id"
 
 
 class Model(models.Model):
+    urlid = LDPUrlField(null=True, unique=True)
 
     @classmethod
     def get_view_set(cls):
@@ -133,20 +135,26 @@ class Model(models.Model):
             permissions = permission_class().filter_user_perms(user_or_group, obj_or_model, permissions)
         return [{'mode': {'@type': name.split('_')[0]}} for name in permissions]
 
+    @classmethod
+    def is_external(cls, value):
+        try:
+            return value.urlid is not None
+        except:
+            return False
+
 
 class LDPSource(Model):
-    id = models.URLField(primary_key=True)
     federation = models.CharField(max_length=255)
 
     class Meta:
         rdf_type = 'ldp:Container'
         ordering = ('federation',)
         container_path = 'sources'
-        lookup_field = 'id'
+        lookup_field = 'federation'
         permissions = (
             ('view_source', 'acl:Read'),
             ('control_source', 'acl:Control'),
         )
 
     def __str__(self):
-        return "{}: {}".format(self.federation, self.id)
+        return "{}: {}".format(self.federation, self.urlid)
diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py
index 5560793a..2d2e96e5 100644
--- a/djangoldp/serializers.py
+++ b/djangoldp/serializers.py
@@ -184,7 +184,10 @@ class JsonLdField(HyperlinkedRelatedField):
 class JsonLdRelatedField(JsonLdField):
     def to_representation(self, value):
         try:
-            return {'@id': super().to_representation(value)}
+            if Model.is_external(value):
+                return {'@id': value.urlid }
+            else:
+                return {'@id': super().to_representation(value)}
         except ImproperlyConfigured:
             return value.pk
 
@@ -223,10 +226,20 @@ class JsonLdIdentityField(JsonLdField):
 
     def to_representation(self, value: Any) -> Any:
         try:
-            return Hyperlink(value.webid(), value)
+            if isinstance(value, str):
+                return Hyperlink(value, value)
+            else:
+                return Hyperlink(value.webid(), value)
         except AttributeError:
             return super().to_representation(value)
 
+    def get_attribute(self, instance):
+        if Model.is_external(instance):
+            return instance.urlid
+        else:
+            return super().get_attribute(instance)
+
+
 
 class LDPSerializer(HyperlinkedModelSerializer):
     url_field_name = "@id"
@@ -254,10 +267,10 @@ class LDPSerializer(HyperlinkedModelSerializer):
         for field in data:
             if isinstance(data[field], dict) and '@id' in data[field]:
                 data[field]['@id'] = data[field]['@id'].format(Model.container_id(obj), str(getattr(obj, slug_field)))
-        if not ('@id' in data or 'id' in data):
+        if 'urlid' in data and data['urlid'] is not None:
+            data['@id'] = data.pop('urlid')['@id']
+        if not '@id' in data:
             data['@id'] = '{}{}'.format(settings.SITE_URL, Model.resource(obj))
-        if 'id' in data:
-            data['@id'] = data.pop('id')
         rdf_type = Model.get_meta(obj, 'rdf_type', None)
         rdf_context = Model.get_meta(obj, 'rdf_context', None)
         if rdf_type is not None:
diff --git a/djangoldp/tests/tests_get.py b/djangoldp/tests/tests_get.py
index fb2c0b99..e69f119f 100644
--- a/djangoldp/tests/tests_get.py
+++ b/djangoldp/tests/tests_get.py
@@ -42,14 +42,17 @@ class TestGET(APITestCase):
     def test_get_filtered_fields(self):
         skill = Skill.objects.create(title="Java", obligatoire="ok", slug="1")
         skill2 = Skill.objects.create(title="Java", obligatoire="ok", slug="2")
+        skill3 = Skill.objects.create(urlid="http://external/skills/1")
         job = JobOffer.objects.create(title="job", slug="1")
         job.skills.add(skill)
         job.skills.add(skill2)
+        job.skills.add(skill3)
         job.save()
         response = self.client.get('/job-offers/{}/'.format(job.slug), content_type='application/ld+json')
         self.assertEqual(response.status_code, 200)
         self.assertIn('recent_skills', response.data)
         self.assertEqual(response.data['recent_skills']['@id'], "http://happy-dev.fr/job-offers/1/recent_skills/")
+        self.assertEqual(response.data['skills']['ldp:contains'][2]['@id'], "http://external/skills/1")
 
     def test_get_reverse_filtered_fields(self):
         skill = Skill.objects.create(title="Java", obligatoire="ok", slug="1")
diff --git a/djangoldp/tests/tests_sources.py b/djangoldp/tests/tests_sources.py
index a68327f5..e43f3e94 100644
--- a/djangoldp/tests/tests_sources.py
+++ b/djangoldp/tests/tests_sources.py
@@ -13,6 +13,6 @@ class TestSource(APITestCase):
         pass
 
     def test_get_resource(self):
-        source = LDPSource.objects.create(federation="source_name", id="http://bar.foo/")
+        source = LDPSource.objects.create(federation="source_name", urlid="http://bar.foo/")
         response = self.client.get('/sources/{}/'.format(source.federation), content_type='application/ld+json')
         self.assertEqual(response.status_code, 200)
diff --git a/djangoldp/tests/tests_temp.py b/djangoldp/tests/tests_temp.py
index 161703c8..6896080d 100644
--- a/djangoldp/tests/tests_temp.py
+++ b/djangoldp/tests/tests_temp.py
@@ -1,11 +1,7 @@
-import json
-
 from django.contrib.auth.models import User
 from django.test import TestCase
 from rest_framework.test import APIRequestFactory, APIClient
 
-from djangoldp.tests.models import Resource, JobOffer, Invoice, Batch
-
 
 class TestTemp(TestCase):
 
@@ -16,4 +12,3 @@ class TestTemp(TestCase):
 
     def tearDown(self):
         pass
-
diff --git a/djangoldp/urls.py b/djangoldp/urls.py
index f92a2ab4..a83b98eb 100644
--- a/djangoldp/urls.py
+++ b/djangoldp/urls.py
@@ -17,7 +17,7 @@ def __clean_path(path):
 
 
 urlpatterns = [
-    url(r'^sources/(?P<federation>\w+)/', LDPSourceViewSet.urls(model=LDPSource, fields=['federation', 'id'],
+    url(r'^sources/(?P<federation>\w+)/', LDPSourceViewSet.urls(model=LDPSource, fields=['federation', 'urlid'],
                                                                 permission_classes=[LDPPermissions], )),
     url(r'^\.well-known/webfinger/?$', WebFingerView.as_view()),
 ]
-- 
GitLab