Repository: techmatters/terraso-backend

Issue:
Landscape creation and update
<!--
Use a concise title that describes the request.
Bad: localization
Good: Translate site into Spanish

Bad: customize hostname
Good: Determine hostname at build time from environment
-->

## Description
- Default landscape group should be created when a new landscape is created
- Manager should be assigned at the creation of a landscape
- Only managers can update landscape data


Discussion:
@josebui 

Just to help on understanding, here are some observations:
- We already have similar behavior. When we create a Group, the user creating it is associated automatically as the Group Manager. Which means, every time a Group model is created, a Membership is also created. Code is here: https://github.com/techmatters/terraso-backend/blob/742f077b5ea819fd01409fada1cd8dd02c8c6579/terraso_backend/apps/core/models/groups.py#L58-L69
- Regarding "Manager should be assigned at the creation of a landscape", this is going to help automatically according to the bullet above. The Landscape manager is nothing more than the manager of default Landscape group

Let me know how else I can help you.
Hey @cacarrara that makes sense to me, I am basing the implementation on that, and that will be reused to achieve the manager requirement.

One doubt I have is the name of the default group, I checked the current default groups on staging and they are called `{landscape name} Group` I was thinking to avoid collisions even more to make it `{landscape name} Default Landscape Group`. Or should ge go one step futher and add a UUID in the name? let me know what do you think
@josebui I think `{landscape name} Default Landscape Group` is too long and UUID isn't that descriptive, considering we would have access to the group name on admin panel, for example. Maybe I would stick with one of the following options:

- `Group {landscape_slug}`
- `{landscape_slug} group`

The current implementation was done without further consideration. The default group names only have this structure because of the `loadsampledata` script. That also have to be updated after this PR:
https://github.com/techmatters/terraso-backend/blob/742f077b5ea819fd01409fada1cd8dd02c8c6579/terraso_backend/apps/core/management/commands/loadsampledata.py#L35-L41

Resolving patch:
diff --git a/terraso_backend/apps/core/models/landscapes.py b/terraso_backend/apps/core/models/landscapes.py
--- a/terraso_backend/apps/core/models/landscapes.py
+++ b/terraso_backend/apps/core/models/landscapes.py
@@ -1,5 +1,5 @@
 import structlog
-from django.db import models
+from django.db import models, transaction
 
 from apps.core import permission_rules as perm_rules
 
@@ -46,6 +46,24 @@ class Meta(SlugModel.Meta):
             "delete": perm_rules.allowed_to_delete_landscape,
         }
 
+    def save(self, *args, **kwargs):
+        with transaction.atomic():
+            creating = not Landscape.objects.filter(pk=self.pk).exists()
+
+            super().save(*args, **kwargs)
+
+            if creating and self.created_by:
+                group = Group(
+                    name="Group {}".format(self.slug),
+                    description="",
+                    created_by=self.created_by,
+                )
+                group.save()
+                landscape_group = LandscapeGroup(
+                    group=group, landscape=self, is_default_landscape_group=True
+                )
+                landscape_group.save()
+
     def get_default_group(self):
         """
         A default Group in a Landscape is that Group where any


Test patch:
diff --git a/terraso_backend/tests/core/models/test_landscapes.py b/terraso_backend/tests/core/models/test_landscapes.py
--- a/terraso_backend/tests/core/models/test_landscapes.py
+++ b/terraso_backend/tests/core/models/test_landscapes.py
@@ -1,8 +1,9 @@
 import pytest
 from mixer.backend.django import mixer
 
-from apps.core.models.groups import Group
+from apps.core.models.groups import Group, Membership
 from apps.core.models.landscapes import Landscape, LandscapeGroup
+from apps.core.models.users import User
 
 pytestmark = pytest.mark.django_db
 
@@ -66,3 +67,12 @@ def test_landscape_get_default_group_without_group_returns_none():
     landscape = mixer.blend(Landscape)
 
     assert landscape.get_default_group() is None
+
+
+def test_landscape_creator_becomes_manager():
+    user = mixer.blend(User)
+    landscape = mixer.blend(Landscape, created_by=user)
+
+    manager_membership = Membership.objects.get(group=landscape.get_default_group(), user=user)
+
+    assert manager_membership.user_role == Membership.ROLE_MANAGER