From 3f23c2e1d3a3f01b821b889f6a270e5abd52cc3b Mon Sep 17 00:00:00 2001
From: Jorran Wit <jorrandewit@outlook.com>
Date: Thu, 15 Dec 2016 18:49:35 +0100
Subject: [PATCH] Move logic from request_commentary to form

Move form validation and saving of instances
to the form class. From here you are able to instantly
save your validated form to the database. Further
reduces the size of the views.
Form may need error handling on not having
found a Contributor before saving the form instance.
---
 commentaries/forms.py |  37 ++++++++++++++++
 commentaries/views.py | 100 +++++++++++++++++++++---------------------
 2 files changed, 87 insertions(+), 50 deletions(-)

diff --git a/commentaries/forms.py b/commentaries/forms.py
index 1209f2d15..65bb327eb 100644
--- a/commentaries/forms.py
+++ b/commentaries/forms.py
@@ -2,6 +2,8 @@ from django import forms
 
 from .models import Commentary
 
+from scipost.models import Contributor
+
 COMMENTARY_ACTION_CHOICES = (
     (0, 'modify'),
     (1, 'accept'),
@@ -29,6 +31,8 @@ class IdentifierToQueryForm(forms.Form):
 
 
 class RequestCommentaryForm(forms.ModelForm):
+    existing_commentary = None
+
     class Meta:
         model = Commentary
         fields = ['type', 'discipline', 'domain', 'subject_area',
@@ -39,6 +43,7 @@ class RequestCommentaryForm(forms.ModelForm):
                   'pub_DOI', 'pub_abstract']
 
     def __init__(self, *args, **kwargs):
+        self.user = kwargs.pop('user', None)
         super(RequestCommentaryForm, self).__init__(*args, **kwargs)
         self.fields['metadata'].widget = forms.HiddenInput()
         self.fields['pub_date'].widget.attrs.update({'placeholder': 'Format: YYYY-MM-DD'})
@@ -47,6 +52,37 @@ class RequestCommentaryForm(forms.ModelForm):
         self.fields['pub_DOI'].widget.attrs.update({'placeholder': 'ex.: 10.21468/00.000.000000'})
         self.fields['pub_abstract'].widget.attrs.update({'cols': 100})
 
+    def clean(self, *args, **kwargs):
+        cleaned_data = super(RequestCommentaryForm, self).clean(*args, **kwargs)
+        if not cleaned_data['arxiv_identifier'] and not cleaned_data['pub_DOI']:
+            msg = ('You must provide either a DOI (for a published paper) '
+                'or an arXiv identifier (for a preprint).')
+            self.add_error('arxiv_identifier', msg)
+            self.add_error('pub_DOI', msg)
+        elif (cleaned_data['arxiv_identifier'] and
+              (Commentary.objects
+               .filter(arxiv_identifier=cleaned_data['arxiv_identifier']).exists())):
+            msg = 'There already exists a Commentary Page on this preprint, see'
+            self.existing_commentary = get_object_or_404(
+                Commentary,
+                arxiv_identifier=cleaned_data['arxiv_identifier'])
+            self.add_error('arxiv_identifier', msg)
+        elif (cleaned_data['pub_DOI'] and
+              Commentary.objects.filter(pub_DOI=cleaned_data['pub_DOI']).exists()):
+            msg = 'There already exists a Commentary Page on this publication, see'
+            self.existing_commentary = get_object_or_404(Commentary, pub_DOI=cleaned_data['pub_DOI'])
+            self.add_error('pub_DOI', msg)
+
+    def save(self, *args, **kwargs):
+        """Prefill instance before save"""
+        self.requested_by = Contributor.objects.get(user=self.user)
+        return super(RequestCommentaryForm, self).save(*args, **kwargs)
+
+    def get_existing_commentary(self):
+        """Get Commentary if found after validation"""
+        return self.existing_commentary
+
+
 class VetCommentaryForm(forms.Form):
     action_option = forms.ChoiceField(widget=forms.RadioSelect,
                                       choices=COMMENTARY_ACTION_CHOICES,
@@ -55,6 +91,7 @@ class VetCommentaryForm(forms.Form):
     email_response_field = forms.CharField(widget=forms.Textarea(
         attrs={'rows': 5, 'cols': 40}), label='Justification (optional)', required=False)
 
+
 class CommentarySearchForm(forms.Form):
     """Search for Commentary specified by user"""
     pub_author = forms.CharField(max_length=100, required=False, label="Author(s)")
diff --git a/commentaries/views.py b/commentaries/views.py
index bdd00b85a..a21319d0c 100644
--- a/commentaries/views.py
+++ b/commentaries/views.py
@@ -6,15 +6,12 @@ import requests
 from django.db.models import Q
 from django.utils import timezone
 from django.shortcuts import get_object_or_404, render
-from django.contrib.auth import authenticate, login, logout
+from django.contrib.auth import login, logout
 from django.contrib.auth.decorators import login_required, permission_required
-from django.contrib.auth.models import User
 from django.core.mail import EmailMessage
 from django.core.urlresolvers import reverse
-from django.http import HttpResponse, HttpResponseRedirect
+from django.http import HttpResponse
 from django.shortcuts import redirect
-from django.views.decorators.csrf import csrf_protect
-from django.db.models import Avg
 
 from .models import Commentary
 from .forms import RequestCommentaryForm, DOIToQueryForm, IdentifierToQueryForm
@@ -35,53 +32,48 @@ from scipost.forms import AuthenticationForm
 @login_required
 @permission_required('scipost.can_request_commentary_pages', raise_exception=True)
 def request_commentary(request):
+    form = RequestCommentaryForm(request.POST or None, user=request.user)
     if request.method == 'POST':
-        form = RequestCommentaryForm(request.POST)
         if form.is_valid():
-            errormessage = ''
-            existing_commentary = None
-            if not form.cleaned_data['arxiv_identifier'] and not form.cleaned_data['pub_DOI']:
-                errormessage = ('You must provide either a DOI (for a published paper) '
-                                'or an arXiv identifier (for a preprint).')
-            elif (form.cleaned_data['arxiv_identifier'] and
-                  (Commentary.objects
-                   .filter(arxiv_identifier=form.cleaned_data['arxiv_identifier']).exists())):
-                errormessage = 'There already exists a Commentary Page on this preprint, see'
-                existing_commentary = get_object_or_404(
-                    Commentary,
-                    arxiv_identifier=form.cleaned_data['arxiv_identifier'])
-            elif (form.cleaned_data['pub_DOI'] and
-                  Commentary.objects.filter(pub_DOI=form.cleaned_data['pub_DOI']).exists()):
-                errormessage = 'There already exists a Commentary Page on this publication, see'
-                existing_commentary = get_object_or_404(Commentary, pub_DOI=form.cleaned_data['pub_DOI'])
-            if errormessage:
-                doiform = DOIToQueryForm()
-                identifierform = IdentifierToQueryForm()
-                context = {'form': form, 'doiform': doiform, 'identifierform': identifierform,
-                           'errormessage': errormessage,
-                           'existing_commentary': existing_commentary}
-                return render(request, 'commentaries/request_commentary.html', context)
+            # errormessage = ''
+            # existing_commentary = None
+            # if not form.cleaned_data['arxiv_identifier'] and not form.cleaned_data['pub_DOI']:
+            #     errormessage = ('You must provide either a DOI (for a published paper) '
+            #                     'or an arXiv identifier (for a preprint).')
+            # elif (form.cleaned_data['arxiv_identifier'] and
+            #       (Commentary.objects
+            #        .filter(arxiv_identifier=form.cleaned_data['arxiv_identifier']).exists())):
+            #     errormessage = 'There already exists a Commentary Page on this preprint, see'
+            #     existing_commentary = get_object_or_404(
+            #         Commentary,
+            #         arxiv_identifier=form.cleaned_data['arxiv_identifier'])
+            # elif (form.cleaned_data['pub_DOI'] and
+            #       Commentary.objects.filter(pub_DOI=form.cleaned_data['pub_DOI']).exists()):
+            #     errormessage = 'There already exists a Commentary Page on this publication, see'
+            #     existing_commentary = get_object_or_404(Commentary, pub_DOI=form.cleaned_data['pub_DOI'])
 
             # Otherwise we can create the Commentary
-            contributor = Contributor.objects.get(user=request.user)
-            commentary = Commentary (
-                requested_by = contributor,
-                type = form.cleaned_data['type'],
-                discipline = form.cleaned_data['discipline'],
-                domain = form.cleaned_data['domain'],
-                subject_area = form.cleaned_data['subject_area'],
-                pub_title = form.cleaned_data['pub_title'],
-                arxiv_identifier = form.cleaned_data['arxiv_identifier'],
-                pub_DOI = form.cleaned_data['pub_DOI'],
-                metadata = form.cleaned_data['metadata'],
-                author_list = form.cleaned_data['author_list'],
-                journal = form.cleaned_data['journal'],
-                volume = form.cleaned_data['volume'],
-                pages = form.cleaned_data['pages'],
-                pub_date = form.cleaned_data['pub_date'],
-                pub_abstract = form.cleaned_data['pub_abstract'],
-                latest_activity = timezone.now(),
-                )
+            # contributor = Contributor.objects.get(user=request.user)
+            # commentary = Commentary(
+            #     requested_by = contributor,
+            #     type = form.cleaned_data['type'],
+            #     discipline = form.cleaned_data['discipline'],
+            #     domain = form.cleaned_data['domain'],
+            #     subject_area = form.cleaned_data['subject_area'],
+            #     pub_title = form.cleaned_data['pub_title'],
+            #     arxiv_identifier = form.cleaned_data['arxiv_identifier'],
+            #     pub_DOI = form.cleaned_data['pub_DOI'],
+            #     metadata = form.cleaned_data['metadata'],
+            #     author_list = form.cleaned_data['author_list'],
+            #     journal = form.cleaned_data['journal'],
+            #     volume = form.cleaned_data['volume'],
+            #     pages = form.cleaned_data['pages'],
+            #     pub_date = form.cleaned_data['pub_date'],
+            #     pub_abstract = form.cleaned_data['pub_abstract'],
+            #     latest_activity = timezone.now(),
+            #     )
+
+            commentary = form.save(commit=False)
             commentary.parse_links_into_urls()
             commentary.save()
 
@@ -91,8 +83,16 @@ def request_commentary(request):
                        'followup_link': reverse('scipost:personal_page'),
                        'followup_link_label': 'personal page'}
             return render(request, 'scipost/acknowledgement.html', context)
-    else:
-        form = RequestCommentaryForm()
+
+        else:
+            doiform = DOIToQueryForm()
+            existing_commentary = form.get_existing_commentary()
+            identifierform = IdentifierToQueryForm()
+            context = {'form': form, 'doiform': doiform, 'identifierform': identifierform,
+                       'errormessage': form.errors,
+                       'existing_commentary': existing_commentary}
+            return render(request, 'commentaries/request_commentary.html', context)
+
     doiform = DOIToQueryForm()
     identifierform = IdentifierToQueryForm()
     context = {'form': form, 'doiform': doiform, 'identifierform': identifierform}
-- 
GitLab