diff --git a/djangoldp/migrations/0003_auto_20190911_0931.py b/djangoldp/migrations/0003_auto_20190911_0931.py
new file mode 100644
index 0000000000000000000000000000000000000000..72aa15bfbea5ed5f146cec65899bd9632fc47dcb
--- /dev/null
+++ b/djangoldp/migrations/0003_auto_20190911_0931.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2019-09-11 09:31
+from __future__ import unicode_literals
+
+from django.db import migrations
+import djangoldp.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('djangoldp', '0002_auto_20190906_0642'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='ldpsource',
+            name='urlid',
+            field=djangoldp.fields.LDPUrlField(blank=True, null=True, unique=True),
+        ),
+    ]
diff --git a/djangoldp/models.py b/djangoldp/models.py
index 3dce34ef3348e1373dd90905fdf09217ba72fa0e..c9f545dca94268162909bd98c87a30370f805f95 100644
--- a/djangoldp/models.py
+++ b/djangoldp/models.py
@@ -2,8 +2,10 @@ from django.conf import settings
 from django.contrib.auth.models import User
 from django.db import models
 from django.db.models.base import ModelBase
+from django.db.models.signals import pre_save, post_save
+from django.dispatch import receiver
 from django.urls import get_resolver
-from django.utils.datastructures import MultiValueDict, MultiValueDictKeyError
+from django.utils.datastructures import MultiValueDictKeyError
 from django.utils.decorators import classonlymethod
 
 from djangoldp.fields import LDPUrlField
@@ -14,7 +16,10 @@ User._meta.owner_field = "id"
 
 
 class Model(models.Model):
-    urlid = LDPUrlField(null=True, unique=True)
+    urlid = LDPUrlField(blank=True, null=True, unique=True)
+
+    def __init__(self, *args, **kwargs):
+        super(Model, self).__init__(*args, **kwargs)
 
     @classmethod
     def get_view_set(cls):
@@ -33,7 +38,10 @@ class Model(models.Model):
         return cls.__clean_path(path)
 
     def get_absolute_url(self):
-        return Model.resource_id(self)
+        if self.urlid is  None or self.urlid != '':
+            return '{}{}'.format(settings.BASE_URL, Model.resource_id(self))
+        else:
+            return self.urlid
 
     def get_container_id(self):
         return Model.container_id(self)
@@ -57,7 +65,7 @@ class Model(models.Model):
         else:
             object_name = instance_or_model._meta.object_name.lower()
         view_name = '{}-detail'.format(object_name)
-        try :
+        try:
             slug_field = '/{}'.format(get_resolver().reverse_dict[view_name][0][0][1][0])
         except MultiValueDictKeyError:
             slug_field = Model.get_meta(instance_or_model, 'lookup_field', 'pk')
@@ -159,3 +167,11 @@ class LDPSource(Model):
 
     def __str__(self):
         return "{}: {}".format(self.federation, self.urlid)
+
+
+@receiver([post_save])
+def auto_urlid(sender, instance, **kwargs):
+    if isinstance(instance, Model) and (instance.urlid is None or instance.urlid == ''):
+        instance.urlid = instance.get_absolute_url()
+        instance.save()
+
diff --git a/djangoldp/tests/models.py b/djangoldp/tests/models.py
index c3bf10a6c537097ab4bd6106577277962f36366b..8d6757635a775089c867996cbc851f8e441bdbef 100644
--- a/djangoldp/tests/models.py
+++ b/djangoldp/tests/models.py
@@ -24,7 +24,7 @@ class Skill(Model):
 
 
 class JobOffer(Model):
-    title = models.CharField(max_length=255, blank=True, null=True)
+    title = models.CharField(max_length=255, null=True)
     skills = models.ManyToManyField(Skill, blank=True)
     slug = models.SlugField(blank=True, null=True, unique=True)
     date = models.DateTimeField(auto_now_add=True, blank=True)
@@ -58,6 +58,7 @@ class Conversation(models.Model):
 
 class Resource(Model):
     joboffers = models.ManyToManyField(JobOffer, blank=True, related_name='resources')
+    description = models.CharField(max_length=255)
 
     class Meta:
         anonymous_perms = ['view', 'add', 'delete', 'add', 'change', 'control']
diff --git a/djangoldp/tests/runner.py b/djangoldp/tests/runner.py
index 9b83a4fc2f7eaa059ada26a6689aceb6e95d284e..f0fb6b439daeedd5d4d86ef00f815fa6138324a8 100644
--- a/djangoldp/tests/runner.py
+++ b/djangoldp/tests/runner.py
@@ -49,7 +49,8 @@ settings.configure(DEBUG=False,
                                    'djangoldp.tests',
                                    ),
                    SITE_URL='http://happy-dev.fr',
-                   REST_FRAMEWORK={
+                   BASE_URL='http://happy-dev.fr',
+                   REST_FRAMEWORK = {
                        'DEFAULT_PAGINATION_CLASS': 'djangoldp.pagination.LDPPagination',
                        'PAGE_SIZE': 5
                    },
@@ -71,7 +72,7 @@ failures = test_runner.run_tests([
     'djangoldp.tests.tests_delete',
     'djangoldp.tests.tests_sources',
     'djangoldp.tests.tests_pagination',
-    'djangoldp.tests.tests_temp'
+    # 'djangoldp.tests.tests_temp'
 
 ])
 if failures:
diff --git a/djangoldp/tests/tests_ldp_model.py b/djangoldp/tests/tests_ldp_model.py
index 14217f94a0dc1985f0ee4ea8d71f64a43caa51e7..bc316ed50914dea6fb6fc99847392fa9d09e2562 100644
--- a/djangoldp/tests/tests_ldp_model.py
+++ b/djangoldp/tests/tests_ldp_model.py
@@ -16,7 +16,7 @@ class LDPModelTest(TestCase):
     def test_class_inheriting_ldp_model(self):
         dummy = LDPDummy.objects.create(some="text")
         self.assertEquals("/ldpdummys/", dummy.get_container_id())
-        self.assertEquals("/ldpdummys/{}/".format(dummy.pk), dummy.get_absolute_url())
+        self.assertEquals("http://happy-dev.fr/ldpdummys/{}/".format(dummy.pk), dummy.get_absolute_url())
         self.assertEquals("/ldpdummys/", Model.container_id(dummy))
         self.assertEquals("/ldpdummys/{}/".format(dummy.pk), Model.resource_id(dummy))
 
@@ -33,6 +33,6 @@ class LDPModelTest(TestCase):
         from django.urls import get_resolver
         dummy = LDPDummy.objects.create(some="text")
         view_name = '{}-list'.format(dummy._meta.object_name.lower())
-        path = '/{}{}/'.format(get_resolver().reverse_dict[view_name][0][0][0], dummy.pk)
+        path = 'http://happy-dev.fr/{}{}/'.format(get_resolver().reverse_dict[view_name][0][0][0], dummy.pk)
 
         self.assertEquals(path, dummy.get_absolute_url())
diff --git a/djangoldp/tests/tests_save.py b/djangoldp/tests/tests_save.py
index 089cb551050e55d9341e7afa801388fcaf5bff76..8885ecb3b1c563a07bd302923887582794c54154 100644
--- a/djangoldp/tests/tests_save.py
+++ b/djangoldp/tests/tests_save.py
@@ -3,7 +3,7 @@ from rest_framework.utils import json
 
 from djangoldp.models import Model
 from djangoldp.serializers import LDPSerializer
-from djangoldp.tests.models import Skill, JobOffer, Invoice, LDPDummy, Resource
+from djangoldp.tests.models import Skill, JobOffer, Invoice, LDPDummy, Resource, Post
 
 
 class Save(TestCase):
@@ -88,8 +88,8 @@ class Save(TestCase):
         self.assertIs(result.skills.count(), 0)
 
     def test_save_m2m_graph_with_nested(self):
-        skill1 = Skill.objects.create(title="skill1", obligatoire="obligatoire")
-        skill2 = Skill.objects.create(title="skill2", obligatoire="obligatoire")
+        skill1 = Skill.objects.create(title="skill1", obligatoire="obligatoire", slug="a")
+        skill2 = Skill.objects.create(title="skill2", obligatoire="obligatoire", slug="b")
 
         job = {"@graph": [
             {"title": "job test",
@@ -111,9 +111,9 @@ class Save(TestCase):
         self.assertEquals(result.skills.all()[0].title, "skill3 NEW")  # creation on the fly
 
     def test_save_without_nested_fields(self):
-        skill1 = Skill.objects.create(title="skill1", obligatoire="obligatoire")
-        skill2 = Skill.objects.create(title="skill2", obligatoire="obligatoire")
-        job = {"title": "job test"}
+        skill1 = Skill.objects.create(title="skill1", obligatoire="obligatoire", slug="a")
+        skill2 = Skill.objects.create(title="skill2", obligatoire="obligatoire", slug="b")
+        job = {"title": "job test", "slug": "c"}
 
         meta_args = {'model': JobOffer, 'depth': 2, 'fields': ("@id", "title", "skills")}
 
@@ -265,7 +265,8 @@ class Save(TestCase):
                                     data=json.dumps(body),
                                     content_type='application/ld+json')
         self.assertEqual(response.status_code, 201)
-        self.assertEqual(response.data['resources']['ldp:contains'][0]['@id'], "http://testserver/resources/{}/".format(resource.pk))
+        self.assertEqual(response.data['resources']['ldp:contains'][0]['@id'],
+                         "http://testserver/resources/{}/".format(resource.pk))
         self.assertEqual(response.data['title'], "new job")
 
     def test_nested_container_federated(self):
@@ -278,7 +279,8 @@ class Save(TestCase):
                                     data=json.dumps(body),
                                     content_type='application/ld+json')
         self.assertEqual(response.status_code, 201)
-        self.assertEqual(response.data['resources']['ldp:contains'][0]['@id'], "http://testserver/resources/{}/".format(resource.pk))
+        self.assertEqual(response.data['resources']['ldp:contains'][0]['@id'],
+                         "http://testserver/resources/{}/".format(resource.pk))
         self.assertEqual(response.data['@id'], "http://external.job/job/1")
 
     def test_embedded_context_2(self):
@@ -294,3 +296,35 @@ class Save(TestCase):
         response = self.client.post('/posts/', data=json.dumps(body),
                                     content_type='application/ld+json')
         self.assertEqual(response.status_code, 201)
+
+    def test_auto_id(self):
+        body = {
+            '@id': "./",
+            'content': "post update",
+            'peer_user': "",
+            '@context': {
+                "@vocab": "http://happy-dev.fr/owl/#",
+            }
+        }
+
+        response = self.client.post('/posts/', data=json.dumps(body),
+                                    content_type='application/ld+json')
+        self.assertEqual(response.status_code, 201)
+        saved_post = Post.objects.get(pk=1)
+        self.assertEqual(saved_post.urlid, "https://happy-dev.fr/posts/1/")
+
+    def test_auto_id(self):
+        body = {
+            '@id': "./",
+            'content': "post update",
+            'peer_user': "",
+            '@context': {
+                "@vocab": "http://happy-dev.fr/owl/#",
+            }
+        }
+
+        response = self.client.post('/posts/', data=json.dumps(body),
+                                    content_type='application/ld+json')
+        self.assertEqual(response.status_code, 201)
+        saved_post = Post.objects.get(pk=1)
+        self.assertEqual(saved_post.urlid, "http://happy-dev.fr/posts/1/")
diff --git a/djangoldp/tests/tests_temp.py b/djangoldp/tests/tests_temp.py
index b3ef7100cea8141b870c33296df8616979c57f10..eaef247795d1c2842633147f9a346149df3a459f 100644
--- a/djangoldp/tests/tests_temp.py
+++ b/djangoldp/tests/tests_temp.py
@@ -2,6 +2,8 @@ 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
+
 
 class TestTemp(TestCase):
 
@@ -13,3 +15,31 @@ class TestTemp(TestCase):
     def tearDown(self):
         pass
 
+    def test_nested_container_federated(self):
+        resource = Resource.objects.create()
+        body = {
+            'http://happy-dev.fr/owl/#@id': "http://external.job/job/1",
+        }
+
+        response = self.client.post('/resources/{}/joboffers/'.format(resource.pk),
+                                    data=json.dumps(body),
+                                    content_type='application/ld+json')
+        self.assertEqual(response.status_code, 201)
+        self.assertEqual(response.data['resources']['ldp:contains'][0]['@id'], "http://testserver/resources/{}/".format(resource.pk))
+        self.assertEqual(response.data['@id'], "http://external.job/job/1")
+
+    def test_m2m_new_link_federated(self):
+        resource = Resource.objects.create()
+        body = {
+            'http://happy-dev.fr/owl/#joboffers': {
+                'http://happy-dev.fr/owl/#@id': 'http://external.job/job/1',
+            }
+        }
+
+        response = self.client.put('/resources/{}/'.format(resource.pk),
+                                   data=json.dumps(body),
+                                   content_type='application/ld+json')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.data['joboffers']['ldp:contains'][0]['@id'],
+                         "http://external.job/job/1")
+
diff --git a/djangoldp/tests/tests_update.py b/djangoldp/tests/tests_update.py
index bbd9846ac2767bd8484a5a19e3dd83a1c8fe83a6..7db97dee730dc73f4dbdaffc8b7546cbdbb3a167 100644
--- a/djangoldp/tests/tests_update.py
+++ b/djangoldp/tests/tests_update.py
@@ -450,7 +450,7 @@ class Update(TestCase):
                                    content_type='application/ld+json')
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.data['joboffers']['ldp:contains'][0]['@id'],
-                         "http://testserver/job-offers/aaa/")
+                         "http://happy-dev.fr/job-offers/aaa/")
         self.assertEqual(response.data['joboffers']['ldp:contains'][0]['title'], "new job")
 
     def test_m2m_existing_link(self):