From 5de965529b7dbd3655560095cbf5a2340255b78e Mon Sep 17 00:00:00 2001
From: Calum Mackervoy <c.mackervoy@gmail.com>
Date: Mon, 15 Jun 2020 16:55:52 +0000
Subject: [PATCH] feature: auto_author_field for Model.meta

---
 README.md                            | 16 +++++++++++++++-
 djangoldp/__init__.py                |  6 +++---
 djangoldp/tests/models.py            |  5 +++--
 djangoldp/tests/tests_auto_author.py | 12 ++++++++++++
 djangoldp/views.py                   |  7 ++++++-
 5 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index 53e8f706..094de48e 100644
--- a/README.md
+++ b/README.md
@@ -301,7 +301,21 @@ class MyModel(models.Model):
         auto_author = 'author_user'
 ```
 
-Now when an instance of `MyModel` is saved, its `author_user` property will be set to the current user. 
+Now when an instance of `MyModel` is saved, its `author_user` property will be set to the authenticated user. 
+
+### auto_author_field
+
+Set this property to make the value of the `auto_author` field a property on the authenticated use.
+
+```python
+class MyModel(models.Model):
+    author_user = models.ForeignKey(settings.AUTH_USER_MODEL)
+    class Meta:
+        auto_author = 'author_user'
+	auto_author_field = 'profile'
+```
+
+Now when an instance of `MyModel` is saved, its `author_user` property will be set to the **profile** of the authenticated user.
 
 ## permissions
 
diff --git a/djangoldp/__init__.py b/djangoldp/__init__.py
index 3d3f8fe2..736d53af 100644
--- a/djangoldp/__init__.py
+++ b/djangoldp/__init__.py
@@ -2,7 +2,7 @@ from django.db.models import options
 
 __version__ = '0.0.0'
 options.DEFAULT_NAMES += (
-    'lookup_field', 'rdf_type', 'rdf_context', 'auto_author', 'owner_field', 'view_set', 'container_path',
-    'permission_classes', 'serializer_fields', 'nested_fields', 'depth', 'anonymous_perms', 'authenticated_perms',
-    'owner_perms')
+    'lookup_field', 'rdf_type', 'rdf_context', 'auto_author', 'auto_author_field', 'owner_field', 'view_set',
+    'container_path', 'permission_classes', 'serializer_fields', 'nested_fields', 'depth', 'anonymous_perms',
+    'authenticated_perms', 'owner_perms')
 default_app_config = 'djangoldp.apps.DjangoldpConfig'
diff --git a/djangoldp/tests/models.py b/djangoldp/tests/models.py
index 3de550a3..14edc707 100644
--- a/djangoldp/tests/models.py
+++ b/djangoldp/tests/models.py
@@ -86,7 +86,7 @@ class Resource(Model):
 
 class UserProfile(Model):
     description = models.CharField(max_length=255, blank=True, null=True)
-    user = models.OneToOneField(settings.AUTH_USER_MODEL)
+    user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='userprofile')
 
     class Meta(Model.Meta):
         anonymous_perms = ['view']
@@ -177,11 +177,12 @@ class Task(models.Model):
 
 class Post(Model):
     content = models.CharField(max_length=255)
-    author = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
+    author = models.ForeignKey(UserProfile, blank=True, null=True)
     peer_user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name="peers_post")
 
     class Meta(Model.Meta):
         auto_author = 'author'
+        auto_author_field = 'userprofile'
         anonymous_perms = ['view', 'add', 'delete', 'add', 'change', 'control']
         authenticated_perms = ['inherit']
         owner_perms = ['inherit']
diff --git a/djangoldp/tests/tests_auto_author.py b/djangoldp/tests/tests_auto_author.py
index 3a095e3e..50095ad2 100644
--- a/djangoldp/tests/tests_auto_author.py
+++ b/djangoldp/tests/tests_auto_author.py
@@ -2,6 +2,7 @@ import json
 
 from django.contrib.auth import get_user_model
 from rest_framework.test import APIRequestFactory, APIClient, APITestCase
+from djangoldp.tests.models import UserProfile
 
 
 class TestAutoAuthor(APITestCase):
@@ -10,6 +11,7 @@ class TestAutoAuthor(APITestCase):
         self.factory = APIRequestFactory()
         self.client = APIClient()
         self.user = get_user_model().objects.create_user(username='john', email='jlennon@beatles.com', password='glass onion')
+        UserProfile.objects.create(user=self.user)
 
     def tearDown(self):
         self.user.delete()
@@ -21,3 +23,13 @@ class TestAutoAuthor(APITestCase):
         response = self.client.post('/posts/', data=json.dumps(post), content_type='application/ld+json')
         self.assertEqual(response.status_code, 201)
         self.assertEquals(response.data['content'], "post content")
+
+    def test_auto_author_field(self):
+        self.client.force_authenticate(user=self.user)
+        post = {
+            '@graph': [{'http://happy-dev.fr/owl/#content': "post content"}]}
+
+        response = self.client.post('/posts/', data=json.dumps(post), content_type='application/ld+json')
+        self.assertEqual(response.status_code, 201)
+        self.assertEquals(response.data['content'], "post content")
+        self.assertIsNotNone(response.data['author'])
diff --git a/djangoldp/views.py b/djangoldp/views.py
index 70a71ee5..ef571f9a 100644
--- a/djangoldp/views.py
+++ b/djangoldp/views.py
@@ -415,7 +415,12 @@ class LDPViewSet(LDPViewSetGenerator):
 
     def perform_create(self, serializer, **kwargs):
         if hasattr(self.model._meta, 'auto_author') and isinstance(self.request.user, get_user_model()):
-            kwargs[self.model._meta.auto_author] = self.request.user
+            # auto_author_field may be set (a field on user which should be made author - e.g. profile)
+            auto_author_field = getattr(self.model._meta, 'auto_author_field', None)
+            if auto_author_field is not None:
+                kwargs[self.model._meta.auto_author] = getattr(self.request.user, auto_author_field, None)
+            else:
+                kwargs[self.model._meta.auto_author] = self.request.user
         serializer.save(**kwargs)
 
     def get_queryset(self, *args, **kwargs):
-- 
GitLab