server/python/django2/renkanmanager/models.py
changeset 614 23416a833ca8
parent 611 f0f07e2b841f
child 615 f3875fbe206a
--- a/server/python/django2/renkanmanager/models.py	Mon Jun 13 14:23:58 2016 +0200
+++ b/server/python/django2/renkanmanager/models.py	Wed Jun 15 16:31:43 2016 +0200
@@ -17,29 +17,32 @@
 auth_user_model = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
 
 class Workspace(models.Model):
-    
-    workspace_guid = models.CharField(max_length=1024, default=uuid.uuid4, unique=True, blank=False, null=False) # typically UUID
+
+    workspace_guid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, blank=False, null=False)
     title = models.CharField(max_length=1024, null=True)
     creator = models.ForeignKey(auth_user_model, blank=True, null=True, related_name="workspace_creator")
     creation_date = models.DateTimeField(auto_now_add=True)
-    
+
     @property
     def renkan_count(self):
-        return Renkan.objects.filter(workspace__workspace_guid=self.workspace_guid).count()
-    
+        #TODO: check count and related objects
+        #return Renkan.objects.filter(workspace__workspace_guid=self.workspace_guid).count()
+        return Renkan.objects.filter(workspace_guid=self.workspace_guid).count()
+
     class Meta:
         app_label = 'renkanmanager'
         permissions = (
             ('view_workspace', 'Can view workspace'),
         )
-        
+
 
 class RenkanManager(models.Manager):
-    
+
     @transaction.atomic
     def create_renkan(self, creator, title='', content='', source_revision=None, workspace = None):
         new_renkan = Renkan()
         new_renkan.creator = creator
+        #TODO: !!! new_renkan_workspace_guid is not set on the new renkan ! only on the content !
         new_renkan_workspace_guid = ""
         new_renkan_title = title
         new_renkan_content = content
@@ -64,7 +67,7 @@
             new_renkan_content_dict = json.loads(new_renkan.validate_json_content(new_renkan_content))
             new_renkan_content_dict["created"] = str(initial_revision.creation_date)
             new_renkan_content_dict["updated"] = str(initial_revision.modification_date)
-        else: 
+        else:
             new_renkan_content_dict = {
                 "id": str(new_renkan.renkan_guid),
                 "title": initial_revision.title,
@@ -80,57 +83,68 @@
         initial_revision.content = json.dumps(new_renkan_content_dict)
         initial_revision.save()
         return new_renkan
-    
+
 class Renkan(models.Model):
-    
-    renkan_guid = models.CharField(max_length=256, default=uuid.uuid4, unique=True, blank=False, null=False) # typically UUID
-    workspace = models.ForeignKey('Workspace', null=True, blank=True, to_field='workspace_guid')
-    source_revision = models.ForeignKey('Revision', null=True, blank=True, related_name="renkan_source_revision", to_field='revision_guid', on_delete=models.SET_NULL)
+
+    renkan_guid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, blank=False, null=False)
+    workspace_guid = models.CharField(max_length=256, blank=True, null=True)
+    current_revision_guid = models.CharField(max_length=256, blank=True, null=True)
+    source_revision_guid = models.CharField(max_length=256, blank=True, null=True)
+
     creator = models.ForeignKey(auth_user_model, blank=True, null=True, related_name="renkan_creator")
     creation_date = models.DateTimeField(auto_now_add=True)
     state = models.IntegerField(default=1)
-    
+
     objects = RenkanManager()
-    
+
     @property
     def revision_count(self):
-        return Revision.objects.filter(parent_renkan__renkan_guid=self.renkan_guid).count()
-    
+        #TODO: check related object count
+        return Revision.objects.filter(parent_renkan_guid=self.renkan_guid).count()
+        #return Revision.objects.filter(parent_renkan__renkan_guid=self.renkan_guid).count()
+
     @property
     def is_copy(self):
-        return bool(self.source_revision)
-    
+        #return bool(self.source_revision)
+        return bool(self.source_revision_guid)
+
     # Current revision object or None if there is none
-    @property
-    def current_revision(self):
-        return Revision.objects.filter(parent_renkan__renkan_guid=self.renkan_guid).order_by('-creation_date').first()
-    
+#    @property
+#    def current_revision(self):
+#        return Revision.objects.filter(parent_renkan__renkan_guid=self.renkan_guid).order_by('-creation_date').first()
+
     # Current revision title
     @property
     def title(self):
-        if self.current_revision:
-            return self.current_revision.title
-        else:
-            return ''
-    
+        current_revision = Revision.objects.get(revision_guid = self.current_revision_guid)
+        return current_revision.title
+        #TODO: not good -> 2 requests
+        #if self.current_revision:
+        #    return self.current_revision.title
+        #else:
+        #    return ''
+
     # Current revision content
     @property
     def content(self):
-        if self.current_revision:
-            return self.current_revision.content
-        else:
-            return ''
-    
+        #TODO: not good -> 2 requests
+        current_revision = Revision.objects.get(revision_guid = self.current_revision_guid)
+        return current_revision.content
+        #if self.current_revision:
+        #    return self.current_revision.content
+        #else:
+        #    return ''
+
     def __unicode__(self):
         return self.renkan_guid
-    
+
     def __str__(self):
         return self.renkan_guid
-    
+
     @transaction.atomic
     def save_renkan(self, updator, timestamp="", title="", content="", create_new_revision=False):
         """
-            Saves over current revision or saves a new revision entirely. 
+            Saves over current revision or saves a new revision entirely.
             Timestamp must be the current revision modification_date.
         """
         if (not timestamp) or ((self.current_revision is not None) and dateparse.parse_datetime(timestamp) < self.current_revision.modification_date):
@@ -144,33 +158,33 @@
             revision_to_update.creator = updator
         else:
             revision_to_update = Revision.objects.select_for_update().get(revision_guid=self.current_revision.revision_guid)
-        
+
         updated_content = self.validate_json_content(content) if content else current_revision.content
         updated_content_dict = json.loads(updated_content)
-        
+
         # If title is passed as arg to the method, update the title in the json
         if title:
             updated_title = title
             updated_content_dict["title"] = title
         # If it is not, we use the one in the json instead
         else:
-            updated_title = updated_content_dict["title"] 
-        
+            updated_title = updated_content_dict["title"]
+
         revision_to_update.modification_date = timezone.now()
         updated_content_dict["updated"] = str(revision_to_update.modification_date)
-        updated_content = json.dumps(updated_content_dict)  
+        updated_content = json.dumps(updated_content_dict)
         revision_to_update.title = updated_title
         revision_to_update.content = updated_content
         if dt_timestamp == revision_to_update.modification_date:
             revision_to_update.modification_date += datetime.resolution
         revision_to_update.last_updated_by = updator
         revision_to_update.save()
-    
+
     def validate_json_content(self, content):
         """
             Checks that the json content is valid (keys and structures), raise a ValidationError if format is wrong or value is wrong (for ids),
             if a key is missing, autocompletes with the empty default value
-            
+
             Returns the validated json string
         """
         try:
@@ -198,7 +212,7 @@
             content_to_validate_dict["views"] = []
         if "users" not in content_to_validate_dict:
             content_to_validate_dict["users"] = []
-        
+
         if type(content_to_validate_dict["nodes"]) is not list:
             raise ValidationError("Provided content has an invalid 'nodes' key: not a list")
         if type(content_to_validate_dict["edges"]) is not list:
@@ -208,43 +222,50 @@
         if type(content_to_validate_dict["users"]) is not list:
             raise ValidationError("Provided content has an invalid 'users' key: not a list")
         return json.dumps(content_to_validate_dict)
-        
-    @transaction.atomic
-    def delete(self):
-        """
-            Deleting a renkan also deletes every related revision
-        """
-        renkan_revisions = Revision.objects.filter(parent_renkan__renkan_guid = self.renkan_guid)
-        for child_revision in renkan_revisions:
-            child_revision.delete()
-        super(Renkan, self).delete()
-        
+
+    #TODO:
+    # @transaction.atomic
+    # def delete(self):
+    #     """
+    #         Deleting a renkan also deletes every related revision
+    #     """
+    #     renkan_revisions = Revision.objects.filter(parent_renkan__renkan_guid = self.renkan_guid)
+    #     for child_revision in renkan_revisions:
+    #         child_revision.delete()
+    #     super(Renkan, self).delete()
+
     class Meta:
         app_label = 'renkanmanager'
         permissions = (
             ('view_renkan', 'Can view renkan'),
         )
 
-        
+
 class Revision(models.Model):
-    
-    revision_guid = models.CharField(max_length=256, default=uuid.uuid4, unique=True) # typically UUID
-    parent_renkan = models.ForeignKey('Renkan', null=False, blank=False, to_field='renkan_guid')
+
+    revision_guid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, blank=False, null=False)
+    parent_renkan_guid = models.CharField(max_length=256)
+    #parent_renkan = models.ForeignKey('Renkan', null=False, blank=False, to_field='renkan_guid')
     title = models.CharField(max_length=1024, null=True, blank=True)
     content = models.TextField(blank=True, null=True)
     creator = models.ForeignKey(auth_user_model, blank=True, null=True, related_name="revision_creator")
     last_updated_by = models.ForeignKey(auth_user_model, blank=True, null=True, related_name="revision_last_updated_by")
     creation_date = models.DateTimeField(auto_now_add=True)
-    modification_date = models.DateTimeField()
-    
+    modification_date = models.DateTimeField(auto_now=True)
+    #modification_date = models.DateTimeField()
+
     @property
     def is_current_revision(self):
+        try:
+            parent_project = Renkan.objects.get(renkan_guid=self.parent_renkan_guid)
+        except Renkan.DoesNotExist: # SHOULD NOT HAPPEN!
+            raise Http404
+        return parent_project.current_revision_guid == self.revision_guid
         # No need to check if parent_renkan.current_revision is not None, as it won't be if we're calling from a revision
-        return self.parent_renkan.current_revision.revision_guid == self.revision_guid
-    
+        #return self.parent_renkan.current_revision.revision_guid == self.revision_guid
+
     class Meta:
         app_label = 'renkanmanager'
         permissions = (
             ('view_revision', 'Can view revision'),
-        )       
-
+        )