diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py
index 1db352730073c1744f44a34759b4900e7878ad04..2a63242876c350e31cab930a251f7bd047fbcff4 100644
--- a/SciPost_v1/settings/base.py
+++ b/SciPost_v1/settings/base.py
@@ -106,7 +106,7 @@ INSTALLED_APPS = (
     'stats',
     'petitions',
     'webpack_loader',
-    'silk',
+    # 'silk',
 )
 
 
@@ -156,7 +156,7 @@ MATHJAX_CONFIG_DATA = {
     }
 
 MIDDLEWARE = (
-    'silk.middleware.SilkyMiddleware',
+    # 'silk.middleware.SilkyMiddleware',
     # 'django.middleware.http.ConditionalGetMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.locale.LocaleMiddleware',
@@ -169,14 +169,14 @@ MIDDLEWARE = (
     'django.middleware.security.SecurityMiddleware',
 )
 
-SILKY_PYTHON_PROFILER = True
-SILKY_PYTHON_PROFILE_BINARY = False
-SILKY_AUTHENTICATION = True
-SILKY_AUTHORIZATION = True
-SILKY_META = True
-SILKY_INTERCEPT_PERCENT = 0
-SILKY_MAX_RECORDED_REQUESTS = 10**4
-SILKY_PERMISSIONS = lambda user: user.is_superuser
+# SILKY_PYTHON_PROFILER = True
+# SILKY_PYTHON_PROFILE_BINARY = False
+# SILKY_AUTHENTICATION = True
+# SILKY_AUTHORIZATION = True
+# SILKY_META = True
+# SILKY_INTERCEPT_PERCENT = 100
+# SILKY_MAX_RECORDED_REQUESTS = 10**4
+# SILKY_PERMISSIONS = lambda user: user.is_superuser
 
 ROOT_URLCONF = 'SciPost_v1.urls'
 
@@ -220,7 +220,7 @@ DATABASES = {
         'USER': get_secret("DB_USER"),
         'PASSWORD': get_secret("DB_PWD"),
         'HOST': '127.0.0.1',
-        'PORT': '5432',
+        'PORT': '5432'
     }
 }
 
diff --git a/notifications/models.py b/notifications/models.py
index a874fd93220ab123f94e8243ee3b70939e3b7677..3f0d1dd553cfac820324b9030c688b2d5558b251 100644
--- a/notifications/models.py
+++ b/notifications/models.py
@@ -110,21 +110,14 @@ class Notification(models.Model):
 
     def mark_toggle(self):
         if self.pseudo_unread:
-            self.unread = False
-            self.pseudo_unread = False
+            self.mark_as_read()
         else:
-            self.unread = True
-            self.pseudo_unread = True
-        self.save()
+            self.mark_as_unread()
 
     def mark_as_read(self):
         if self.unread or self.pseudo_unread:
-            self.unread = False
-            self.pseudo_unread = False
-            self.save()
+            Notification.objects.filter(id=self.id).update(unread=False, pseudo_unread=False)
 
     def mark_as_unread(self):
         if not self.unread or not self.pseudo_unread:
-            self.unread = True
-            self.pseudo_unread = True
-            self.save()
+            Notification.objects.filter(id=self.id).update(unread=True, pseudo_unread=True)
diff --git a/submissions/forms.py b/submissions/forms.py
index 87e0a091470860ecb4257fdbf1a7679584c5d742..0d69c032e27cd11aee788f5a1e6fea8510ebe865 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -342,38 +342,30 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
         if not self.last_submission:
             raise Submission.DoesNotExist
 
-        # Open for comment and reporting
-        submission.open_for_reporting = True
-        submission.open_for_commenting = True
-
         # Close last submission
-        self.last_submission.is_current = False
-        self.last_submission.open_for_reporting = False
-        self.last_submission.status = STATUS_RESUBMITTED
-        self.last_submission.save()
-
-        # Editor-in-charge
-        submission.editor_in_charge = self.last_submission.editor_in_charge
-        submission.status = STATUS_RESUBMISSION_INCOMING
-
-        # Author claim fields
+        Submission.objects.filter(id=self.last_submission.id).update(
+            is_current=False,
+            open_for_reporting=False,
+            status=STATUS_RESUBMITTED)
+
+        # Open for comment and reporting and copy EIC info
+        Submission.objects.filter(id=submission.id).update(
+            open_for_reporting=True,
+            open_for_commenting=True,
+            editor_in_charge=self.last_submission.editor_in_charge,
+            status=STATUS_RESUBMISSION_INCOMING)
+
+        # Add author(s) (claim) fields
         submission.authors.add(*self.last_submission.authors.all())
         submission.authors_claims.add(*self.last_submission.authors_claims.all())
         submission.authors_false_claims.add(*self.last_submission.authors_false_claims.all())
-        submission.save()
-        return submission
 
-    @transaction.atomic
-    def reassign_eic_and_admins(self, submission):
-        # Assign editor
+        # Create new EditorialAssigment for the current Editor-in-Charge
         assignment = EditorialAssignment(
             submission=submission,
-            to=submission.editor_in_charge,
-            accepted=True
-        )
+            to=self.last_submission.editor_in_charge,
+            accepted=True)
         assignment.save()
-        submission.save()
-        return submission
 
     def set_pool(self, submission):
         qs = Fellowship.objects.active()
@@ -410,8 +402,7 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
         # Save
         submission.save()
         if self.submission_is_resubmission():
-            submission = self.copy_and_save_data_from_resubmission(submission)
-            submission = self.reassign_eic_and_admins(submission)
+            self.copy_and_save_data_from_resubmission(submission)
         submission.authors.add(self.requested_by.contributor)
         self.set_pool(submission)
         return submission
@@ -540,7 +531,7 @@ class ReportForm(forms.ModelForm):
         if kwargs.get('instance'):
             if kwargs['instance'].is_followup_report:
                 # Prefill data from latest report in the series
-                latest_report = kwargs['instance'].latest_report_from_series()
+                latest_report = kwargs['instance'].latest_report_from_thread()
                 kwargs.update({
                     'initial': {
                         'qualification': latest_report.qualification,
@@ -834,7 +825,7 @@ class SubmissionCycleChoiceForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.fields['refereeing_cycle'].default = None
-        other_submissions = self.instance.other_versions_pool.all()
+        other_submissions = self.instance.other_versions.all()
         if other_submissions:
             self.fields['referees_reinvite'].queryset = RefereeInvitation.objects.filter(
                 submission__in=other_submissions).distinct()
diff --git a/submissions/models.py b/submissions/models.py
index 94d82f7bb68a16fb90871648598cd987ae27110a..c0b667037792148367ad5cc3ad82bf003c6266a2 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -13,36 +13,38 @@ from django.urls import reverse
 from django.utils.functional import cached_property
 
 from .behaviors import SubmissionRelatedObjectMixin
-from .constants import ASSIGNMENT_REFUSAL_REASONS, ASSIGNMENT_NULLBOOL,\
-                       SUBMISSION_TYPE, ED_COMM_CHOICES, REFEREE_QUALIFICATION, QUALITY_SPEC,\
-                       RANKING_CHOICES, REPORT_REC, SUBMISSION_STATUS, STATUS_UNASSIGNED,\
-                       REPORT_STATUSES, STATUS_UNVETTED, SUBMISSION_EIC_RECOMMENDATION_REQUIRED,\
-                       SUBMISSION_CYCLES, CYCLE_DEFAULT, CYCLE_SHORT, CYCLE_DIRECT_REC,\
-                       EVENT_GENERAL, EVENT_TYPES, EVENT_FOR_AUTHOR, EVENT_FOR_EIC,\
-                       REPORT_TYPES, REPORT_NORMAL, STATUS_DRAFT, STATUS_VETTED,\
-                       STATUS_VOTING_IN_PREPARATION, STATUS_PUT_TO_EC_VOTING
-from .managers import SubmissionQuerySet, EditorialAssignmentQuerySet, EICRecommendationQuerySet,\
-                      ReportQuerySet, SubmissionEventQuerySet, RefereeInvitationQuerySet,\
-                      EditorialCommunicationQueryset
-from .utils import ShortSubmissionCycle, DirectRecommendationSubmissionCycle,\
-                   GeneralSubmissionCycle
+from .constants import (
+    ASSIGNMENT_REFUSAL_REASONS, ASSIGNMENT_NULLBOOL, SUBMISSION_TYPE,
+    ED_COMM_CHOICES, REFEREE_QUALIFICATION, QUALITY_SPEC, RANKING_CHOICES, REPORT_REC,
+    SUBMISSION_STATUS, STATUS_UNASSIGNED, REPORT_STATUSES, STATUS_UNVETTED,
+    SUBMISSION_EIC_RECOMMENDATION_REQUIRED, SUBMISSION_CYCLES, CYCLE_DEFAULT, CYCLE_SHORT,
+    CYCLE_DIRECT_REC, EVENT_GENERAL, EVENT_TYPES, EVENT_FOR_AUTHOR, EVENT_FOR_EIC, REPORT_TYPES,
+    REPORT_NORMAL, STATUS_DRAFT, STATUS_VETTED, STATUS_VOTING_IN_PREPARATION,
+    STATUS_PUT_TO_EC_VOTING)
+from .managers import (
+    SubmissionQuerySet, EditorialAssignmentQuerySet, EICRecommendationQuerySet, ReportQuerySet,
+    SubmissionEventQuerySet, RefereeInvitationQuerySet, EditorialCommunicationQueryset)
+from .utils import (
+    ShortSubmissionCycle, DirectRecommendationSubmissionCycle, GeneralSubmissionCycle)
 
 from comments.models import Comment
 from scipost.behaviors import TimeStampedModel
 from scipost.constants import TITLE_CHOICES
-from scipost.fields import ChoiceArrayField
 from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS
+from scipost.fields import ChoiceArrayField
 from journals.constants import SCIPOST_JOURNALS_SUBMIT, SCIPOST_JOURNALS_DOMAINS
 from journals.models import Publication
 
 
 class Submission(models.Model):
+    """SciPost register of an preprint (ArXiv articles only for now).
+
+    A Submission is a centralized information package used in the refereeing cycle of a preprint.
+    It collects information about authors, referee reports, editorial recommendations,
+    college decisions, etc. etc. After an 'acceptance editorial recommendation', the Publication
+    will directly be related to the latest Submission in the thread.
     """
-    Submission is a SciPost register of an ArXiv article. This object is the central
-    instance for every action, recommendation, communication, etc. etc. that is related to the
-    refereeing cycle of a Submission. A possible Publication object is later directly related
-    to this Submission instance.
-    """
+
     author_comments = models.TextField(blank=True)
     author_list = models.CharField(max_length=1000, verbose_name="author list")
     discipline = models.CharField(max_length=20, choices=SCIPOST_DISCIPLINES, default='physics')
@@ -120,24 +122,24 @@ class Submission(models.Model):
     class Meta:
         app_label = 'submissions'
 
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-        self._update_cycle()
-
     def save(self, *args, **kwargs):
-        # Fill `arxiv_identifier_w_vn_nr` as a dummy field for convenience
+        """Prefill some fields before saving."""
         arxiv_w_vn = '{arxiv}v{version}'.format(
             arxiv=self.arxiv_identifier_wo_vn_nr,
             version=self.arxiv_vn_nr)
         self.arxiv_identifier_w_vn_nr = arxiv_w_vn
 
         obj = super().save(*args, **kwargs)
-        self._update_cycle()
+        if hasattr(self, 'cycle'):
+            self.set_cycle()
         return obj
 
     def __str__(self):
-        header = (self.arxiv_identifier_w_vn_nr + ', '
-                  + self.title[:30] + ' by ' + self.author_list[:30])
+        """Summerize the Submission in a string."""
+        header = '{arxiv_id}, {title} by {authors}'.format(
+            arxiv_id=self.arxiv_identifier_w_vn_nr,
+            title=self.title[:30],
+            authors=self.author_list[:30])
         if self.is_current:
             header += ' (current version)'
         else:
@@ -148,99 +150,105 @@ class Submission(models.Model):
         return header
 
     def touch(self):
-        """ Update latest activity as a service """
-        self.latest_activity = timezone.now()
-        self.save()
+        """Update latest activity timestamp."""
+        Submission.objects.filter(id=self.id).update(latest_activity=timezone.now())
 
     def comments_set_complete(self):
-        """
-        Return comments to Submission, comments on Reports of Submission and
-        nested comments related to this Submission.
-        """
+        """Return Comments on Submissions, Reports and other Comments."""
         return Comment.objects.filter(Q(submissions=self) |
                                       Q(reports__submission=self) |
                                       Q(comments__reports__submission=self) |
                                       Q(comments__submissions=self)).distinct()
 
-    def _update_cycle(self):
-        """
-        Append the specific submission cycle to the instance to eventually handle the
-        complete submission cycle outside the submission instance itself.
-        """
+    @property
+    def cycle(self):
+        """Get cycle object that's relevant for the Submission."""
+        print('asdfs')
+        if not hasattr(self, '__cycle'):
+            self.set_cycle()
+        return self.__cycle
+
+    def set_cycle(self):
+        """Set cycle to the Submission on request."""
         if self.refereeing_cycle == CYCLE_SHORT:
-            self.cycle = ShortSubmissionCycle(self)
+            cycle = ShortSubmissionCycle(self)
         elif self.refereeing_cycle == CYCLE_DIRECT_REC:
-            self.cycle = DirectRecommendationSubmissionCycle(self)
+            cycle = DirectRecommendationSubmissionCycle(self)
         else:
-            self.cycle = GeneralSubmissionCycle(self)
+            cycle = GeneralSubmissionCycle(self)
+        self.__cycle = cycle
 
     def get_absolute_url(self):
-        return reverse('submissions:submission', args=[self.arxiv_identifier_w_vn_nr])
+        """Return url of the Submission detail page."""
+        return reverse('submissions:submission', args=(self.arxiv_identifier_w_vn_nr,))
 
     @property
     def notification_name(self):
+        """Return string representation of this Submission as shown in Notifications."""
         return self.arxiv_identifier_w_vn_nr
 
     @property
     def eic_recommendation_required(self):
+        """Return if Submission needs a EICRecommendation to be formulated."""
         return self.status in SUBMISSION_EIC_RECOMMENDATION_REQUIRED
 
     @property
     def reporting_deadline_has_passed(self):
+        """Check if Submission has passed it's reporting deadline."""
         return timezone.now() > self.reporting_deadline
 
     @property
     def original_submission_date(self):
+        """Return the submission_date of the first Submission in the thread."""
         return Submission.objects.filter(
             arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr).first().submission_date
 
     @cached_property
     def thread(self):
-        """
-        Return all versions of the Submission with that arxiv id.
-        """
+        """Return all (public) Submissions in the database in this ArXiv identifier series."""
         return Submission.objects.public().filter(
-            arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr
-        ).order_by('-arxiv_vn_nr')
+            arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr).order_by('-arxiv_vn_nr')
 
     @cached_property
-    def other_versions(self):
-        """
-        Return all other versions of the Submission that are publicly accessible.
-        """
+    def other_versions_public(self):
+        """Return other (public) Submissions in the database in this ArXiv identifier series."""
         return Submission.objects.public().filter(
             arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr
         ).exclude(pk=self.id).order_by('-arxiv_vn_nr')
 
     @cached_property
-    def other_versions_pool(self):
-        """
-        Return all other versions of the Submission.
-        """
+    def other_versions(self):
+        """Return other Submissions in the database in this ArXiv identifier series."""
         return Submission.objects.filter(
-            arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr
-        ).exclude(pk=self.id).order_by('-arxiv_vn_nr')
+            arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr).exclude(
+            pk=self.id).order_by('-arxiv_vn_nr')
 
-    # Underneath: All very inefficient methods as they initiate a new query
     def count_accepted_invitations(self):
+        """Count number of accepted RefereeInvitations for this Submission."""
         return self.referee_invitations.filter(accepted=True).count()
 
     def count_declined_invitations(self):
+        """Count number of declined RefereeInvitations for this Submission."""
         return self.referee_invitations.filter(accepted=False).count()
 
     def count_pending_invitations(self):
+        """Count number of RefereeInvitations awaiting response for this Submission."""
         return self.referee_invitations.filter(accepted=None).count()
 
     def count_invited_reports(self):
+        """Count number of invited Reports for this Submission."""
         return self.reports.accepted().filter(invited=True).count()
 
     def count_contrib_reports(self):
+        """Count number of contributed Reports for this Submission."""
         return self.reports.accepted().filter(invited=False).count()
 
     def count_obtained_reports(self):
+        """Count total number of Reports for this Submission."""
         return self.reports.accepted().filter(invited__isnull=False).count()
 
     def add_general_event(self, message):
+        """Generate message meant for EIC and authors."""
         event = SubmissionEvent(
             submission=self,
             event=EVENT_GENERAL,
@@ -249,6 +257,7 @@ class Submission(models.Model):
         event.save()
 
     def add_event_for_author(self, message):
+        """Generate message meant for authors only."""
         event = SubmissionEvent(
             submission=self,
             event=EVENT_FOR_AUTHOR,
@@ -257,6 +266,7 @@ class Submission(models.Model):
         event.save()
 
     def add_event_for_eic(self, message):
+        """Generate message meant for EIC and Editorial Administration only."""
         event = SubmissionEvent(
             submission=self,
             event=EVENT_FOR_EIC,
@@ -266,16 +276,16 @@ class Submission(models.Model):
 
 
 class SubmissionEvent(SubmissionRelatedObjectMixin, TimeStampedModel):
-    """
-    The SubmissionEvent's goal is to act as a messaging/logging model
-    for the Submission cycle. Its main audience will be the author(s) and
-    the Editor-in-charge of a Submission.
+    """Private message directly related to a Submission.
+
+    The SubmissionEvent's goal is to act as a messaging model for the Submission cycle.
+    Its main audience will be the author(s) and the Editor-in-charge of a Submission.
 
-    Be aware!
-    Both the author and editor-in-charge will read the submission event.
-    Make sure the right text is given to the right event-type, to protect
+    Be aware that both the author and editor-in-charge will read the submission event.
+    Make sure the right text is given to the appropriate event-type, to protect
     the fellow's identity.
     """
+
     submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE,
                                    related_name='events')
     event = models.CharField(max_length=4, choices=EVENT_TYPES, default=EVENT_GENERAL)
@@ -287,6 +297,7 @@ class SubmissionEvent(SubmissionRelatedObjectMixin, TimeStampedModel):
         ordering = ['-created']
 
     def __str__(self):
+        """Summerize the SubmissionEvent's meta information."""
         return '%s: %s' % (str(self.submission), self.get_event_display())
 
 
@@ -295,11 +306,13 @@ class SubmissionEvent(SubmissionRelatedObjectMixin, TimeStampedModel):
 ######################
 
 class EditorialAssignment(SubmissionRelatedObjectMixin, models.Model):
+    """Unique Fellow assignment to a Submission as Editor-in-Charge.
+
+    An EditorialAssignment could be an invitation to be the Editor-in-Charge for a Submission,
+    containing either its acceptance or rejection, or it is an immediate accepted assignment. In
+    addition is registers whether the Fellow's duties are fullfilled or still ongoing.
     """
-    EditorialAssignment is a registration for Fellows of their duties of being a
-    Editor-in-charge for a specific Submission. This model could start as a invitation only,
-    which should then be accepted or declined by the invited.
-    """
+
     submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE)
     to = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE)
     accepted = models.NullBooleanField(choices=ASSIGNMENT_NULLBOOL, default=None)
@@ -319,19 +332,29 @@ class EditorialAssignment(SubmissionRelatedObjectMixin, models.Model):
         ordering = ['-date_created']
 
     def __str__(self):
+        """Summerize the EditorialAssignment's basic information."""
         return (self.to.user.first_name + ' ' + self.to.user.last_name + ' to become EIC of ' +
                 self.submission.title[:30] + ' by ' + self.submission.author_list[:30] +
                 ', requested on ' + self.date_created.strftime('%Y-%m-%d'))
 
     def get_absolute_url(self):
+        """Return url of the assignment's processing page."""
         return reverse('submissions:assignment_request', args=(self.id,))
 
     @property
     def notification_name(self):
+        """Return string representation of this EditorialAssigment as shown in Notifications."""
         return self.submission.arxiv_identifier_w_vn_nr
 
 
 class RefereeInvitation(SubmissionRelatedObjectMixin, models.Model):
+    """Invitation to a scientist to referee a Submission.
+
+    A RefereeInvitation will invite a Contributor or a non-registered scientist to send
+    a Report for a specific Submission. It will register its response to the invitation and
+    the current status its refereeing duty if the invitation has been accepted.
+    """
+
     submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE,
                                    related_name='referee_invitations')
     referee = models.ForeignKey('scipost.Contributor', related_name='referee_invitations',
@@ -340,6 +363,7 @@ class RefereeInvitation(SubmissionRelatedObjectMixin, models.Model):
     first_name = models.CharField(max_length=30)
     last_name = models.CharField(max_length=30)
     email_address = models.EmailField()
+
     # if Contributor not found, person is invited to register
     invitation_key = models.CharField(max_length=40)
     date_invited = models.DateTimeField(default=timezone.now)
@@ -357,28 +381,34 @@ class RefereeInvitation(SubmissionRelatedObjectMixin, models.Model):
     objects = RefereeInvitationQuerySet.as_manager()
 
     def __str__(self):
+        """Summerize the RefereeInvitation's basic information."""
         return (self.first_name + ' ' + self.last_name + ' to referee ' +
                 self.submission.title[:30] + ' by ' + self.submission.author_list[:30] +
                 ', invited on ' + self.date_invited.strftime('%Y-%m-%d'))
 
     def get_absolute_url(self):
+        """Return url of the invitation's processing page."""
         return reverse('submissions:accept_or_decline_ref_invitations', args=(self.id,))
 
     @property
     def referee_str(self):
+        """Return the most up-to-date name of the Referee."""
         if self.referee:
             return str(self.referee)
         return self.last_name + ', ' + self.first_name
 
     @property
     def notification_name(self):
+        """Return string representation of this RefereeInvitation as shown in Notifications."""
         return self.submission.arxiv_identifier_w_vn_nr
 
     @property
     def related_report(self):
+        """Return the Report that's been created for this invitation."""
         return self.submission.reports.filter(author=self.referee).first()
 
     def reset_content(self):
+        """Reset the invitation's information as a new invitation."""
         self.nr_reminders = 0
         self.date_last_reminded = None
         self.accepted = None
@@ -392,17 +422,14 @@ class RefereeInvitation(SubmissionRelatedObjectMixin, models.Model):
 ###########
 
 class Report(SubmissionRelatedObjectMixin, models.Model):
-    """
-    Both types of reports, invited or contributed.
-
-    This Report model acts as both a regular `Report` and a `FollowupReport`; A normal Report
-    should have all fields required, whereas a FollowupReport only has the `report` field as
-    a required field.
+    """Report on a Submission written by a Contributor.
 
-    Important note!
-    Due to the construction of the two different types within a single model, it is important
-    to explicitly implement the perticular differences in for example the form used.
+    The refereeing Report has evaluation (text) fields for different categories. In general,
+    the Report shall have all of these fields filled. In case the Contributor has already written
+    a Report on a earlier version of the Submission, he will be able to write a 'follow-up report'.
+    A follow-up report is a Report with only the general `report` evaluation field being required.
     """
+
     status = models.CharField(max_length=16, choices=REPORT_STATUSES, default=STATUS_UNVETTED)
     report_type = models.CharField(max_length=32, choices=REPORT_TYPES, default=REPORT_NORMAL)
     submission = models.ForeignKey('submissions.Submission', related_name='reports',
@@ -468,71 +495,68 @@ class Report(SubmissionRelatedObjectMixin, models.Model):
         ordering = ['-date_submitted']
 
     def __str__(self):
+        """Summerize the RefereeInvitation's basic information."""
         return (self.author.user.first_name + ' ' + self.author.user.last_name + ' on ' +
                 self.submission.title[:50] + ' by ' + self.submission.author_list[:50])
 
-    @property
-    def is_in_draft(self):
-        return self.status == STATUS_DRAFT
-
-    @property
-    def is_vetted(self):
-        return self.status == STATUS_VETTED
-
     def save(self, *args, **kwargs):
-        # Control Report count per Submission.
+        """Update report number before saving on creation."""
         if not self.report_nr:
             self.report_nr = self.submission.reports.count() + 1
         return super().save(*args, **kwargs)
 
-    def create_doi_label(self):
-        self.doi_label = 'SciPost.Report.' + str(self.id)
-        self.save()
-
     def get_absolute_url(self):
+        """Return url of the Report on the Submission detail page."""
         return self.submission.get_absolute_url() + '#report_' + str(self.report_nr)
 
+    @property
+    def is_in_draft(self):
+        """Return if Report is in draft."""
+        return self.status == STATUS_DRAFT
+
+    @property
+    def is_vetted(self):
+        """Return if Report is publicly available."""
+        return self.status == STATUS_VETTED
+
     @property
     def notification_name(self):
+        """Return string representation of this Report as shown in Notifications."""
         return self.submission.arxiv_identifier_w_vn_nr
 
     @property
     def doi_string(self):
+        """Return the doi with the registrant identifier prefix."""
         if self.doi_label:
             return '10.21468/' + self.doi_label
         return ''
 
     @cached_property
     def title(self):
-        """
+        """Return the submission's title.
+
         This property is (mainly) used to let Comments get the title of the Submission without
-        annoying logic.
+        overcomplicated logic.
         """
         return self.submission.title
 
     @property
     def is_followup_report(self):
-        """
-        Check if current Report is a `FollowupReport`. A Report is a `FollowupReport` if the
-        author of the report already has a vetted report in the series of the specific Submission.
+        """Return if Report is a follow-up Report instead of a regular Report.
+
+        This property is used in the ReportForm, but will be candidate to become a database
+        field if this information will become necessary in more general information representation.
         """
         return (self.author.reports.accepted().filter(
             submission__arxiv_identifier_wo_vn_nr=self.submission.arxiv_identifier_wo_vn_nr,
             submission__arxiv_vn_nr__lt=self.submission.arxiv_vn_nr).exists())
 
-    def latest_report_from_series(self):
-        """
-        Get latest Report from the same author for the Submission series.
-        """
-        return (self.author.reports.accepted().filter(
-            submission__arxiv_identifier_wo_vn_nr=self.submission.arxiv_identifier_wo_vn_nr)
-                .order_by('submission__arxiv_identifier_wo_vn_nr').last())
-
     @property
     def associated_published_doi(self):
-        """
-        Check if the Report relates to a SciPost-published object.
-        If it is, return the doi of the published object.
+        """Return the related Publication doi.
+
+        Check if the Report relates to a SciPost-published object. If it is, return the doi
+        of the published object.
         """
         try:
             publication = Publication.objects.get(
@@ -543,10 +567,10 @@ class Report(SubmissionRelatedObjectMixin, models.Model):
 
     @property
     def relation_to_published(self):
-        """
-        Check if the Report relates to a SciPost-published object.
-        If it is, return a dict with info on relation to the published object,
-        based on Crossref's peer review content type.
+        """Return dictionary with published object information.
+
+        Check if the Report relates to a SciPost-published object. If it is, return a dict with
+        info on relation to the published object, based on Crossref's peer review content type.
         """
         try:
             publication = Publication.objects.get(
@@ -565,6 +589,7 @@ class Report(SubmissionRelatedObjectMixin, models.Model):
 
     @property
     def citation(self):
+        """Return the proper citation format for this Report."""
         citation = ''
         if self.doi_string:
             if self.anonymous:
@@ -576,16 +601,24 @@ class Report(SubmissionRelatedObjectMixin, models.Model):
             citation += 'doi: %s' % self.doi_string
         return citation
 
+    def create_doi_label(self):
+        """Create a doi in the default format."""
+        Report.objects.filter(id=self.id).update(doi_label='SciPost.Report.{}'.format(self.id))
+
+    def latest_report_from_thread(self):
+        """Get latest Report of this Report's author for the Submission thread."""
+        return self.author.reports.accepted().filter(
+            submission__arxiv_identifier_wo_vn_nr=self.submission.arxiv_identifier_wo_vn_nr
+        ).order_by('submission__arxiv_identifier_wo_vn_nr').last()
+
 
 ##########################
 # EditorialCommunication #
 ##########################
 
 class EditorialCommunication(SubmissionRelatedObjectMixin, models.Model):
-    """
-    Each individual communication between Editor-in-charge
-    to and from Referees and Authors becomes an instance of this class.
-    """
+    """Message between two of the EIC, referees, Editorial Administration and/or authors."""
+
     submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE)
     referee = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE,
                                 blank=True, null=True)
@@ -600,20 +633,24 @@ class EditorialCommunication(SubmissionRelatedObjectMixin, models.Model):
         default_related_name = 'editorial_communications'
 
     def __str__(self):
+        """Summerize the EditorialCommunication's meta information."""
         output = self.comtype
         if self.referee is not None:
             output += ' ' + self.referee.user.first_name + ' ' + self.referee.user.last_name
-        output += (' for submission ' + self.submission.title[:30] + ' by '
-                   + self.submission.author_list[:30])
+        output += ' for submission {title} by {authors}'.format(
+            title=self.submission.title[:30],
+            authors=self.submission.author_list[:30])
         return output
 
 
 class EICRecommendation(SubmissionRelatedObjectMixin, models.Model):
+    """The recommendation formulated for a specific Submission, formulated by the EIC.
+
+    The EICRecommendation is the recommendation of a Submission written by the Editor-in-charge
+    formulated at the end of the refereeing cycle. It can be voted for by a subset of Fellows and
+    should contain the actual publication decision.
     """
-    The EICRecommendation is the recommendation of a Submission written by
-    the Editor-in-charge made at the end of the refereeing cycle. It can be voted for by
-    a subset of Fellows and should contain the actual publication decision.
-    """
+
     submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE,
                                    related_name='eicrecommendations')
     date_submitted = models.DateTimeField('date submitted', default=timezone.now)
@@ -643,6 +680,7 @@ class EICRecommendation(SubmissionRelatedObjectMixin, models.Model):
         ordering = ['version']
 
     def __str__(self):
+        """Summerize the EICRecommendation's meta information."""
         return '{title} by {author}, {recommendation} version {version}'.format(
             title=self.submission.title[:20],
             author=self.submission.author_list[:30],
@@ -651,26 +689,35 @@ class EICRecommendation(SubmissionRelatedObjectMixin, models.Model):
         )
 
     def get_absolute_url(self):
-        # TODO: Fix this weird redirect, but it's neccesary for the notifications to have one.
+        """Return url of the Submission detail page.
+
+        Note that the EICRecommendation is not publicly visible, so the use of this url
+        is limited.
+        """
         return self.submission.get_absolute_url()
 
     @property
     def notification_name(self):
+        """Return string representation of this EICRecommendation as shown in Notifications."""
         return self.submission.arxiv_identifier_w_vn_nr
 
     @property
     def nr_for(self):
+        """Return the number of votes 'for'."""
         return self.voted_for.count()
 
     @property
     def nr_against(self):
+        """Return the number of votes 'against'."""
         return self.voted_against.count()
 
     @property
     def nr_abstained(self):
+        """Return the number of votes 'abstained'."""
         return self.voted_abstain.count()
 
     def may_be_reformulated(self):
+        """Check if this EICRecommdation is allowed to be reformulated in a new version."""
         if not self.active:
             # Already reformulated before; please use the latest version
             return False
@@ -678,10 +725,12 @@ class EICRecommendation(SubmissionRelatedObjectMixin, models.Model):
 
 
 class iThenticateReport(TimeStampedModel):
+    """iThenticate report registration.
+
+    iThenticateReport is the SciPost register of an iThenticate report saving basic information
+    coming from iThenticate into the SciPost database for easy access.
     """
-    iThenticateReport is the SciPost register of an iThenticate report. It saves
-    basic information coming from iThenticate into the SciPost database for easy access.
-    """
+
     uploaded_time = models.DateTimeField(null=True, blank=True)
     processed_time = models.DateTimeField(null=True, blank=True)
     doc_id = models.IntegerField(primary_key=True)
@@ -692,16 +741,31 @@ class iThenticateReport(TimeStampedModel):
         verbose_name = 'iThenticate Report'
         verbose_name_plural = 'iThenticate Reports'
 
+    def __str__(self):
+        """Summerize the iThenticateReport's meta information."""
+        _str = 'Report {doc_id}'.format(doc_id=self.doc_id)
+        if hasattr(self, 'to_submission'):
+            _str += ' on Submission {arxiv}'.format(
+                arxiv=self.to_submission.arxiv_identifier_w_vn_nr)
+        return _str
+
+    def save(self, *args, **kwargs):
+        """Update the Submission's latest update timestamp on update."""
+        obj = super().save(*args, **kwargs)
+        if hasattr(self, 'to_submission') and kwargs.get('commit', True):
+            self.to_submission.touch()
+        return obj
+
     def get_absolute_url(self):
+        """Return url of the plagiarism detail page."""
         if hasattr(self, 'to_submission'):
-            return reverse('submissions:plagiarism', kwargs={
-                            'arxiv_identifier_w_vn_nr':
-                            self.to_submission.arxiv_identifier_w_vn_nr})
-        return None
+            return reverse(
+                'submissions:plagiarism',
+                kwargs={'arxiv_identifier_w_vn_nr': self.to_submission.arxiv_identifier_w_vn_nr})
+        return ''
 
     def get_report_url(self):
-        """
-        Request new read-only url from iThenticate and return.
+        """Request and return new read-only url from the iThenticate API.
 
         Note: The read-only link is valid for only 15 minutes, saving may be worthless
         """
@@ -712,19 +776,7 @@ class iThenticateReport(TimeStampedModel):
         plagiarism = iThenticate()
         return plagiarism.get_url(self.part_id)
 
-    def __str__(self):
-        _str = 'Report {doc_id}'.format(doc_id=self.doc_id)
-        if hasattr(self, 'to_submission'):
-            _str += ' on Submission {arxiv}'.format(
-                        arxiv=self.to_submission.arxiv_identifier_w_vn_nr)
-        return _str
-
-    def save(self, *args, **kwargs):
-        obj = super().save(*args, **kwargs)
-        if hasattr(self, 'to_submission') and kwargs.get('commit', True):
-            self.to_submission.touch()
-        return obj
-
     @property
     def score(self):
+        """Return the iThenticate score returned by their API as saved in the database."""
         return self.percent_match
diff --git a/submissions/utils.py b/submissions/utils.py
index 4cf92f3e174b850bce492de508c3d4409accedf7..44115064ba9bfc12aced5a0b3e6d217b9f1b7404 100644
--- a/submissions/utils.py
+++ b/submissions/utils.py
@@ -8,11 +8,10 @@ from django.core.mail import EmailMessage, EmailMultiAlternatives
 from django.template import Context, Template
 from django.utils import timezone
 
-from .constants import NO_REQUIRED_ACTION_STATUSES, STATUS_VETTED, STATUS_UNCLEAR,\
-                       STATUS_INCORRECT, STATUS_NOT_USEFUL, STATUS_NOT_ACADEMIC,\
-                       STATUS_REVISION_REQUESTED, STATUS_EIC_ASSIGNED,\
-                       STATUS_RESUBMISSION_INCOMING, STATUS_AWAITING_ED_REC
-from .exceptions import CycleUpdateDeadlineError
+from .constants import (
+    NO_REQUIRED_ACTION_STATUSES, STATUS_VETTED, STATUS_UNCLEAR, STATUS_INCORRECT,
+    STATUS_NOT_USEFUL, STATUS_NOT_ACADEMIC, STATUS_REVISION_REQUESTED, STATUS_EIC_ASSIGNED,
+    STATUS_RESUBMISSION_INCOMING, STATUS_AWAITING_ED_REC)
 
 from scipost.utils import EMAIL_FOOTER
 from common.utils import BaseMailUtil
@@ -124,8 +123,9 @@ class BaseSubmissionCycle:
         """
         delta_d = period or self.default_days
         deadline = timezone.now() + datetime.timedelta(days=delta_d)
-        self.submission.reporting_deadline = deadline
-        self.submission.save()
+
+        from .models import Submission
+        Submission.objects.filter(id=self.submission.id).update(reporting_deadline=deadline)
 
     def get_required_actions(self):
         '''Return list of the submission its required actions'''
@@ -159,8 +159,8 @@ class BaseRefereeSubmissionCycle(BaseSubmissionCycle):
     """
     def update_status(self):
         if self.submission.status == STATUS_RESUBMISSION_INCOMING:
-            self.submission.status = STATUS_EIC_ASSIGNED
-            self.submission.save()
+            from .models import Submission
+            Submission.objects.filter(id=self.submission.id).update(status=STATUS_EIC_ASSIGNED)
 
     def _update_actions(self):
         continue_update = super()._update_actions()
@@ -236,8 +236,8 @@ class DirectRecommendationSubmissionCycle(BaseSubmissionCycle):
 
     def update_status(self):
         if self.submission.status == STATUS_RESUBMISSION_INCOMING:
-            self.submission.status = STATUS_AWAITING_ED_REC
-            self.submission.save()
+            from .models import Submission
+            Submission.objects.filter(id=self.submission.id).update(status=STATUS_AWAITING_ED_REC)
 
     def _update_actions(self):
         continue_update = super()._update_actions()
@@ -276,11 +276,8 @@ class SubmissionUtils(BaseMailUtil):
         # Import here due to circular import error
         from .models import EditorialAssignment
 
-        assignments_to_deprecate = (EditorialAssignment.objects
-                                    .filter(submission=cls.submission, accepted=None))
-        for atd in assignments_to_deprecate:
-            atd.deprecated = True
-            atd.save()
+        EditorialAssignment.objects.filter(
+            submission=cls.submission, accepted=None).update(deprecated=True)
 
     @classmethod
     def reinvite_referees_email(cls):
diff --git a/submissions/views.py b/submissions/views.py
index 1d3fdc11c74e7329e884f3034546d2d0db14276d..25b5e5eb4baeb347360a0e340a46a6f989f285ce 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -23,7 +23,7 @@ from django.views.generic.edit import CreateView, UpdateView
 from django.views.generic.list import ListView
 
 from guardian.shortcuts import assign_perm
-from silk.profiling.profiler import silk_profile
+# from silk.profiling.profiler import silk_profile
 
 from .constants import STATUS_VETTED, STATUS_EIC_ASSIGNED,\
                        SUBMISSION_STATUS_PUBLICLY_INVISIBLE, SUBMISSION_STATUS,\
@@ -354,7 +354,7 @@ def editorial_workflow(request):
 
 @login_required
 @fellowship_or_admin_required()
-@silk_profile(name='Pool')
+# @silk_profile(name='Pool')
 def pool(request, arxiv_identifier_w_vn_nr=None):
     """
     The Submissions pool contains all submissions which are undergoing
@@ -440,8 +440,8 @@ def add_remark(request, arxiv_identifier_w_vn_nr):
 @login_required
 @permission_required('scipost.can_assign_submissions', raise_exception=True)
 def assign_submission(request, arxiv_identifier_w_vn_nr):
-    """
-    Assign Editor-in-charge to Submission.
+    """Assign Editor-in-charge to Submission.
+
     Action done by SciPost Administration or Editorial College Administration.
     """
     submission = get_object_or_404(Submission.objects.pool_editable(request.user),
@@ -465,9 +465,7 @@ def assign_submission(request, arxiv_identifier_w_vn_nr):
 @fellowship_required()
 @transaction.atomic
 def assignment_request(request, assignment_id):
-    """
-    Process EditorialAssignment acceptance/denial form or show if not submitted.
-    """
+    """Process EditorialAssignment acceptance/rejection form or show if not submitted."""
     assignment = get_object_or_404(EditorialAssignment.objects.open(),
                                    to=request.user.contributor, pk=assignment_id)
 
@@ -540,7 +538,7 @@ def assignment_request(request, assignment_id):
 @login_required
 @fellowship_required()
 @transaction.atomic
-@silk_profile(name='Volunteer as EIC')
+# @silk_profile(name='Volunteer as EIC')
 def volunteer_as_EIC(request, arxiv_identifier_w_vn_nr):
     """
     Called when a Fellow volunteers while perusing the submissions pool.
@@ -635,7 +633,7 @@ def assignment_failed(request, arxiv_identifier_w_vn_nr):
 
 @login_required
 @fellowship_required()
-@silk_profile(name='EditorialAssignment overview')
+# @silk_profile(name='EditorialAssignment overview')
 def assignments(request):
     """
     This page provides a Fellow with an explicit task list
@@ -761,7 +759,7 @@ def select_referee(request, arxiv_identifier_w_vn_nr):
 @login_required
 @fellowship_or_admin_required()
 @transaction.atomic
-@silk_profile(name='Recruit referee')
+# @silk_profile(name='Recruit referee')
 def recruit_referee(request, arxiv_identifier_w_vn_nr):
     """
     If the Editor-in-charge does not find the desired referee among Contributors
@@ -874,7 +872,7 @@ def send_refereeing_invitation(request, arxiv_identifier_w_vn_nr, contributor_id
 
 @login_required
 @fellowship_or_admin_required()
-@silk_profile(name='Remind Referee')
+# @silk_profile(name='Remind Referee')
 def ref_invitation_reminder(request, arxiv_identifier_w_vn_nr, invitation_id):
     """
     This method is used by the Editor-in-charge from the editorial_page
@@ -1182,7 +1180,7 @@ def communication(request, arxiv_identifier_w_vn_nr, comtype, referee_id=None):
 @login_required
 @fellowship_or_admin_required()
 @transaction.atomic
-@silk_profile(name='Editorial Assignment processing')
+# @silk_profile(name='Editorial Assignment processing')
 def eic_recommendation(request, arxiv_identifier_w_vn_nr):
     """
     Write EIC Recommendation.
@@ -1370,7 +1368,7 @@ def vet_submitted_reports_list(request):
 @login_required
 @fellowship_or_admin_required()
 @transaction.atomic
-@silk_profile(name='Vet submitted Report')
+# @silk_profile(name='Vet submitted Report')
 def vet_submitted_report(request, report_id):
     """
     Report with status `unvetted` will be shown. A user may only vet reports of submissions
@@ -1592,7 +1590,7 @@ def fix_College_decision(request, rec_id):
     elif recommendation.recommendation == -3:
         # Reject + update-reject other versions of submission
         submission.status = 'rejected'
-        for sub in submission.other_versions_pool:
+        for sub in submission.other_versions:
             sub.status = 'resubmitted_rejected'
             sub.save()