diff --git a/general.py b/general.py deleted file mode 100644 index 5570b662718dd4458c5d43ddd33f02efb8df178d..0000000000000000000000000000000000000000 --- a/general.py +++ /dev/null @@ -1,110 +0,0 @@ -from django.conf.urls import url -from django.urls import reverse_lazy -from django.views.generic import TemplateView, RedirectView - -from journals import views as journals_views - -urlpatterns = [ - # Journals - url(r'^$', journals_views.journals, name='journals'), - url(r'scipost_physics', RedirectView.as_view(url=reverse_lazy('scipost:landing_page', - args=['SciPostPhys']))), - url(r'^journals_terms_and_conditions$', - TemplateView.as_view(template_name='journals/journals_terms_and_conditions.html'), - name='journals_terms_and_conditions'), - url(r'^crossmark_policy$', - TemplateView.as_view(template_name='journals/crossmark_policy.html'), - name='crossmark_policy'), - - # Editorial and Administrative Workflow - url(r'^initiate_publication$', - journals_views.initiate_publication, - name='initiate_publication'), - url(r'^validate_publication$', - journals_views.validate_publication, - name='validate_publication'), - url(r'^mark_first_author/(?P<publication_id>[0-9]+)/(?P<contributor_id>[0-9]+)$', - journals_views.mark_first_author, - name='mark_first_author'), - url(r'^mark_first_author_unregistered/(?P<publication_id>[0-9]+)/(?P<unregistered_author_id>[0-9]+)$', - journals_views.mark_first_author_unregistered, - name='mark_first_author_unregistered'), - url(r'^add_author/(?P<publication_id>[0-9]+)/(?P<contributor_id>[0-9]+)$', - journals_views.add_author, - name='add_author'), - url(r'^add_author/(?P<publication_id>[0-9]+)$', - journals_views.add_author, - name='add_author'), - url(r'^add_unregistered_author/(?P<publication_id>[0-9]+)/(?P<unregistered_author_id>[0-9]+)$', - journals_views.add_unregistered_author, - name='add_unregistered_author'), - url(r'^add_new_unreg_author/(?P<publication_id>[0-9]+)$', - journals_views.add_new_unreg_author, - name='add_new_unreg_author'), - url(r'^manage_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.manage_metadata, - name='manage_metadata'), - url(r'^manage_metadata/(?P<issue_doi_label>[a-zA-Z]+.[0-9]+.[0-9]+)$', - journals_views.manage_metadata, - name='manage_metadata'), - url(r'^manage_metadata/$', - journals_views.manage_metadata, - name='manage_metadata'), - url(r'^create_citation_list_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.create_citation_list_metadata, - name='create_citation_list_metadata'), - url(r'^create_funding_info_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.create_funding_info_metadata, - name='create_funding_info_metadata'), - url(r'^add_associated_grant/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.add_associated_grant, - name='add_associated_grant'), - url(r'^add_generic_funder/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.add_generic_funder, - name='add_generic_funder'), - url(r'^create_metadata_xml/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.create_metadata_xml, - name='create_metadata_xml'), - url(r'^metadata_xml_deposit/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/(?P<option>[a-z]+)$', - journals_views.metadata_xml_deposit, - name='metadata_xml_deposit'), - url(r'^mark_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$', - journals_views.mark_deposit_success, - name='mark_deposit_success'), - url(r'^produce_metadata_DOAJ/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.produce_metadata_DOAJ, - name='produce_metadata_DOAJ'), - url(r'^metadata_DOAJ_deposit/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.metadata_DOAJ_deposit, - name='metadata_DOAJ_deposit'), - url(r'^mark_doaj_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$', - journals_views.mark_doaj_deposit_success, - name='mark_doaj_deposit_success'), - url(r'^harvest_citedby_list/$', - journals_views.harvest_citedby_list, - name='harvest_citedby_list'), - url(r'^harvest_citedby_links/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.harvest_citedby_links, - name='harvest_citedby_links'), - url(r'^sign_existing_report/(?P<report_id>[0-9]+)$', - journals_views.sign_existing_report, - name='sign_existing_report'), - url(r'^manage_report_metadata/$', - journals_views.manage_report_metadata, - name='manage_report_metadata'), - url(r'^manage_comment_metadata/$', - journals_views.manage_comment_metadata, - name='manage_comment_metadata'), - url(r'^mark_report_doi_needed/(?P<report_id>[0-9]+)/(?P<needed>[0-1])$', - journals_views.mark_report_doi_needed, - name='mark_report_doi_needed'), - url(r'^mark_comment_doi_needed/(?P<comment_id>[0-9]+)/(?P<needed>[0-1])$', - journals_views.mark_comment_doi_needed, - name='mark_comment_doi_needed'), - url(r'^generic_metadata_xml_deposit/(?P<type_of_object>[a-z]+)/(?P<object_id>[0-9]+)$', - journals_views.generic_metadata_xml_deposit, - name='generic_metadata_xml_deposit'), - url(r'^mark_generic_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$', - journals_views.mark_generic_deposit_success, - name='mark_generic_deposit_success'), -] diff --git a/journals/admin.py b/journals/admin.py index 5aff8e167e095df8f086ba9002fc7eaa29a3e80f..18468831ac764f2d2ff54862f5052828fb56044f 100644 --- a/journals/admin.py +++ b/journals/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin, messages from django import forms from journals.models import UnregisteredAuthor, Journal, Volume, Issue, Publication, \ - Deposit, DOAJDeposit, GenericDOIDeposit, Reference + Deposit, DOAJDeposit, GenericDOIDeposit, Reference, PublicationAuthorsTable from scipost.models import Contributor from submissions.models import Submission @@ -59,16 +59,21 @@ class ReferenceInline(admin.TabularInline): model = Reference +class AuthorsInline(admin.TabularInline): + model = PublicationAuthorsTable + extra = 0 + + class PublicationAdmin(admin.ModelAdmin): search_fields = ['title', 'author_list'] list_display = ['title', 'author_list', 'in_issue', 'doi_string', 'publication_date'] date_hierarchy = 'publication_date' list_filter = ['in_issue'] - inlines = [ReferenceInline] + inlines = [AuthorsInline, ReferenceInline] form = PublicationAdminForm -admin.site.register(Publication, PublicationAdmin) +admin.site.register(Publication, PublicationAdmin) class DepositAdmin(admin.ModelAdmin): diff --git a/journals/forms.py b/journals/forms.py index bcbf9ce526eed8f1877e32df781652cd0744e4f1..44462b752ef726690395007f2765d454a0e597fa 100644 --- a/journals/forms.py +++ b/journals/forms.py @@ -6,7 +6,7 @@ from django import forms from django.forms import BaseModelFormSet, modelformset_factory from django.utils import timezone -from .models import UnregisteredAuthor, Issue, Publication, Reference +from .models import Issue, Publication, Reference, UnregisteredAuthor from scipost.services import DOICaller from submissions.models import Submission @@ -32,7 +32,7 @@ class ValidatePublicationForm(forms.ModelForm): class UnregisteredAuthorForm(forms.ModelForm): class Meta: model = UnregisteredAuthor - fields = ['first_name', 'last_name'] + fields = ('first_name', 'last_name') class CitationListBibitemsForm(forms.Form): diff --git a/journals/migrations/0009_auto_20180212_1947.py b/journals/migrations/0009_auto_20180212_1947.py new file mode 100644 index 0000000000000000000000000000000000000000..3b45ebe54173af16e913f2dc9bbae27edffeec70 --- /dev/null +++ b/journals/migrations/0009_auto_20180212_1947.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-02-12 18:47 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0008_auto_20180203_1229'), + ] + + operations = [ + migrations.RenameField( + model_name='publication', + old_name='authors', + new_name='authors_old', + ), + migrations.RenameField( + model_name='publication', + old_name='authors_unregistered', + new_name='authors_unregistered_old', + ), + ] diff --git a/journals/migrations/0010_auto_20180212_1947.py b/journals/migrations/0010_auto_20180212_1947.py new file mode 100644 index 0000000000000000000000000000000000000000..6b60b98e106555c74c4a014fb5363a68dc642a8d --- /dev/null +++ b/journals/migrations/0010_auto_20180212_1947.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-02-12 18:47 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0009_auto_20180212_1947'), + ] + + operations = [ + migrations.AlterField( + model_name='publication', + name='authors_old', + field=models.ManyToManyField(blank=True, related_name='publications_old', to='scipost.Contributor'), + ), + migrations.AlterField( + model_name='publication', + name='authors_unregistered_old', + field=models.ManyToManyField(blank=True, related_name='publications_old', to='journals.UnregisteredAuthor'), + ), + ] diff --git a/journals/migrations/0011_auto_20180212_1950.py b/journals/migrations/0011_auto_20180212_1950.py new file mode 100644 index 0000000000000000000000000000000000000000..a6003ecac3699d13d09452f5c629a5f212f3c487 --- /dev/null +++ b/journals/migrations/0011_auto_20180212_1950.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-02-12 18:50 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('scipost', '0004_auto_20180212_1932'), + ('journals', '0010_auto_20180212_1947'), + ] + + operations = [ + migrations.CreateModel( + name='PublicationAuthorsTable', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('order', models.PositiveSmallIntegerField()), + ('contributor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='scipost.Contributor')), + ('publication', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='authors', to='journals.Publication')), + ('unregistered_author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='journals.UnregisteredAuthor')), + ], + options={ + 'ordering': ('order',), + }, + ), + migrations.AddField( + model_name='publication', + name='authors_registered', + field=models.ManyToManyField(blank=True, related_name='publications', through='journals.PublicationAuthorsTable', to='scipost.Contributor'), + ), + migrations.AddField( + model_name='publication', + name='authors_unregistered', + field=models.ManyToManyField(blank=True, related_name='publications', through='journals.PublicationAuthorsTable', to='journals.UnregisteredAuthor'), + ), + ] diff --git a/journals/migrations/0012_auto_20180212_1950.py b/journals/migrations/0012_auto_20180212_1950.py new file mode 100644 index 0000000000000000000000000000000000000000..69128e76f801ab5d082083e6c4405eb244bc5042 --- /dev/null +++ b/journals/migrations/0012_auto_20180212_1950.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-02-12 18:50 +from __future__ import unicode_literals + +from django.db import migrations + + +def transfer_publication_authors_to_separate_table(apps, schema_editor): + Contributor = apps.get_model('scipost', 'Contributor') + Publication = apps.get_model('journals', 'Publication') + UnregisteredAuthor = apps.get_model('journals', 'UnregisteredAuthor') + PublicationAuthorsTable = apps.get_model('journals', 'PublicationAuthorsTable') + + for publication in Publication.objects.all(): + registered_authors = Contributor.objects.filter(publications_old__id=publication.id) + unregistered_authors = UnregisteredAuthor.objects.filter(publications_old__id=publication.id) + + count = 1 + for author in registered_authors: + PublicationAuthorsTable.objects.create( + publication=publication, + contributor=author, + order=count, + ) + count += 1 + + for author in unregistered_authors: + PublicationAuthorsTable.objects.create( + publication=publication, + unregistered_author=author, + order=count, + ) + count += 1 + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0011_auto_20180212_1950'), + ] + + operations = [ + migrations.RunPython(transfer_publication_authors_to_separate_table) + ] diff --git a/journals/models.py b/journals/models.py index c583a4c5221d25c8d9f2f6cc0b95493b0e06a683..41cd2052cc1ad1bdaba0b9852ff8219190edc51e 100644 --- a/journals/models.py +++ b/journals/models.py @@ -30,6 +30,46 @@ class UnregisteredAuthor(models.Model): return self.last_name + ', ' + self.first_name +class PublicationAuthorsTable(models.Model): + publication = models.ForeignKey('journals.Publication', related_name='authors') + unregistered_author = models.ForeignKey('journals.UnregisteredAuthor', null=True, blank=True, + related_name='+') + contributor = models.ForeignKey('scipost.Contributor', null=True, blank=True, related_name='+') + order = models.PositiveSmallIntegerField() + + class Meta: + ordering = ('order',) + + def __str__(self): + if self.contributor: + return str(self.contributor) + elif self.unregistered_author: + return str(self.unregistered_author) + + def save(self, *args, **kwargs): + if not self.order: + self.order = self.publication.authors.count() + 1 + return super().save(*args, **kwargs) + + @property + def is_registered(self): + return self.contributor is not None + + @property + def first_name(self): + if self.contributor: + return self.contributor.user.first_name + if self.unregistered_author: + return self.unregistered_author.first_name + + @property + def last_name(self): + if self.contributor: + return self.contributor.user.last_name + if self.unregistered_author: + return self.unregistered_author.last_name + + class Journal(models.Model): name = models.CharField(max_length=100, choices=SCIPOST_JOURNALS, unique=True) doi_label = models.CharField(max_length=200, unique=True, db_index=True, @@ -240,9 +280,15 @@ class Publication(models.Model): models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS), blank=True, null=True) # Authors - authors = models.ManyToManyField('scipost.Contributor', blank=True, - related_name='publications') + authors_registered = models.ManyToManyField('scipost.Contributor', blank=True, + through='PublicationAuthorsTable', + through_fields=('publication', 'contributor'), + related_name='publications') authors_unregistered = models.ManyToManyField('journals.UnregisteredAuthor', blank=True, + through='PublicationAuthorsTable', + through_fields=( + 'publication', + 'unregistered_author'), related_name='publications') first_author = models.ForeignKey('scipost.Contributor', blank=True, null=True, on_delete=models.CASCADE, @@ -282,6 +328,12 @@ class Publication(models.Model): latest_metadata_update = models.DateTimeField(blank=True, null=True) latest_activity = models.DateTimeField(default=timezone.now) + # Deprecated fields. About to be removed after successful database migration on production. + authors_old = models.ManyToManyField('scipost.Contributor', blank=True, + related_name='publications_old') + authors_unregistered_old = models.ManyToManyField('journals.UnregisteredAuthor', blank=True, + related_name='publications_old') + objects = PublicationQuerySet.as_manager() def __str__(self): diff --git a/journals/templates/journals/add_author.html b/journals/templates/journals/add_author.html index ab992648f64fb3493cddf54a540158efd4478983..b49a3a0408821feaf3c8ddcc5ca28cb7e9dc1e94 100644 --- a/journals/templates/journals/add_author.html +++ b/journals/templates/journals/add_author.html @@ -29,18 +29,16 @@ <div class="row"> <div class="col-12"> - <h3>Current list of authors as contributors:</h3> + <h3>Current list of authors</h3> <ul> {% for author in publication.authors.all %} - <li><a href="{% url 'scipost:contributor_info' author.id %}">{{ author.user.first_name }} {{ author.user.last_name }}</a></li> - {% empty %} - <li>No unregistered authors known.</li> - {% endfor %} - </ul> - <h3>Current list of additional authors (unregistered):</h3> - <ul> - {% for author in publication.authors_unregistered.all %} - <li>{{ author }}</li> + <li> + {% if author.is_registered %} + <a href="{{ author.contributor.get_absolute_url }}">{{ author.contributor }}</a> + {% else %} + {{ author.unregistered_author }} + {% endif %} + </li> {% empty %} <li>No unregistered authors known.</li> {% endfor %} @@ -49,54 +47,38 @@ <br> <h2 class="highlight">Add an (unregistered) author</h2> - <h3>Search for missing author:</h3> - <form action="{% url 'journals:add_author' publication.id %}" method="post"> - {% csrf_token %} - {{form|bootstrap}} + <h3>Search for missing author</h3> + <form method="get"> + {{ form|bootstrap }} <input class="btn btn-primary" type="submit" value="Search"> </form> {% if form.has_changed %} - <br> - <h3 class="mt-2">Identified as contributor:</h3> - <ul class="list-group"> + <br> + <h3>Identified as Contributor:</h3> + <ul> {% for contributor in contributors_found %} - <li class="list-group-item p-2"> - <div class="d-block w-100 font-weight-bold">{{ contributor.user.first_name }} {{ contributor.user.last_name }}</div> - <a class="d-block" href="{% url 'journals:add_author' publication_id=publication.id contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a> + <li> + <div class="font-weight-bold">{{ contributor.user.first_name }} {{ contributor.user.last_name }}</div> + <a href="{% url 'journals:add_author' publication_id=publication.id contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a> </li> {% empty %} - <span class="text-danger">No Contributor with this name could be identified.</span> + <li><span class="text-danger">No Contributor with this name could be identified.</span></li> {% endfor %} </ul> - <h3 class="mt-2">Identified as existing unregistered author:</h3> - <ul class="list-group"> - {% for unreg_auth in unregistered_authors_found %} - <li class="list-group-item"> - <div class="d-block w-100 font-weight-bold">{{ unreg_auth }} - <a class="d-block" href="{% url 'journals:add_unregistered_author' publication_id=publication.id unregistered_author_id=unreg_auth.id %}">Add this unregistered author as author of this Publication</a> - </li> - {% empty %} - <span class="text-danger">No UnregisteredAuthor with this name could be found in the database.</span> - {% endfor %} - </ul> - - <h3 class="mt-3">You can otherwise create an UnregisteredAuthor object instance and link it to this publication:</h3> - <form action="{% url 'journals:add_new_unreg_author' publication_id=publication.id %}" method="post"> + <h3>You can otherwise add the author manually and link it to the publication</h3> + <form action="{% url 'journals:add_author' publication_id=publication.id %}" method="post"> {% csrf_token %} - {{ new_unreg_author_form|bootstrap }} + {{ form|bootstrap }} <input class="btn btn-primary" type="submit" value="Add"> </form> - + <br> {% endif %} - - <br> - <h3> - <a href="{{publication.get_absolute_url}}">Return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a>. - </h3> </div> </div> +<p>Return to the <a href="{{publication.get_absolute_url}}">publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a>.</p> + {% endblock content %} diff --git a/journals/templates/journals/manage_metadata.html b/journals/templates/journals/manage_metadata.html index 56f960111f3f71caae0111c8e6ca43e3a8150e75..0b0547b47c5be8f52046bbf7b3036ac80089d857 100644 --- a/journals/templates/journals/manage_metadata.html +++ b/journals/templates/journals/manage_metadata.html @@ -74,20 +74,11 @@ event: "focusin" <div class="row"> <div class="col-md-5"> <ul> - <li>Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }} {% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %}) - <p>registered authors:</p> - <ul> + <li>Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }}{% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %}) + <ul class="list-unstyled pl-4"> {% for author in publication.authors.all %} <li> - <a href="{% url 'journals:mark_first_author' publication_id=publication.id contributor_id=author.id %}">{{ author }}</a> - </li> - {% endfor %} - </ul> - <p>unregistered authors:</p> - <ul> - {% for author_unreg in publication.authors_unregistered.all %} - <li> - <a href="{% url 'journals:mark_first_author_unregistered' publication_id=publication.id unregistered_author_id=author_unreg.id %}">{{ author_unreg }}</a> + {{ author.order }}. <a href="{% url 'journals:mark_first_author' publication_id=publication.id author_object_id=author.id %}">{{ author }}</a> </li> {% endfor %} </ul> diff --git a/journals/templates/journals/publication_detail.html b/journals/templates/journals/publication_detail.html index 56ed342a757de2b909f8ebac9ccf157cb6ee8e7f..358a8bbca484f3651103a84b22d9df4e010f28b9 100644 --- a/journals/templates/journals/publication_detail.html +++ b/journals/templates/journals/publication_detail.html @@ -20,10 +20,11 @@ <meta name="citation_title" content="{{ publication.title }}"/> {% for author in publication.authors.all %} - <meta name="citation_author" content="{{ author.user.last_name }}, {{ author.user.first_name }}"/> - {% endfor %} - {% for author in publication.authors_unregistered.all %} - <meta name="citation_author" content="{{ author.last_name }}, {{ author.first_name }}"/> + {% if author.contributor %} + <meta name="citation_author" content="{{ author.contributor.user.last_name }}, {{ author.contributor.user.first_name }}"/> + {% elif author.unregistered_author %} + <meta name="citation_author" content="{{ author.unregistered_author.last_name }}, {{ author.unregistered_author.first_name }}"/> + {% endif %} {% endfor %} <meta name="citation_doi" content="{{ publication.doi_string }}"/> <meta name="citation_publication_date" content="{{ publication.publication_date|date:'Y/m/d' }}"/> @@ -83,10 +84,11 @@ <h3>Authors</h3> <ul> {% for author in publication.authors.all %} - <li><a href="{{author.get_absolute_url}}">{{ author }}</a></li> - {% endfor %} - {% for author in publication.authors_unregistered.all %} - <li>{{ author }}</li> + {% if author.is_registered %} + <li><a href="{{ author.contributor.get_absolute_url }}">{{ author.contributor }}</a></li> + {% else %} + <li>{{ author.unregistered_author }}</li> + {% endif %} {% endfor %} </ul> @@ -96,7 +98,7 @@ {# This function is not available for public yet! #} <em>The following is not available for the public yet:</em> {% include 'partials/journals/references.html' with publication=publication %} - + {% if publication.funders_generic.exists %} <h3>Funder{{ publication.funders_generic.count|pluralize }} for this publication:</h3> <ul> @@ -118,7 +120,7 @@ </div> </div> - {% if request.user and request.user.contributor in publication.authors.all %} + {% if request.user and request.user.contributor in publication.registered_authors.all %} <h3>Author actions</h3> <ul> <li><a href="{% url 'commentaries:comment_on_publication' publication.doi_label %}">Place a comment on this publication</a></li> @@ -131,29 +133,15 @@ <div class="col-12"> <h3>Editorial Administration tools: </h3> <ul> - <li>Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }} {% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %}) - <div class="row"> - <div class="col-md-5"> - <p>registered authors:</p> - <ul> - {% for author in publication.authors.all %} - <li> - <a href="{% url 'journals:mark_first_author' publication_id=publication.id contributor_id=author.id %}">{{ author }}</a> - </li> - {% endfor %} - </ul> - </div> - <div class="col-md-5"> - <p>unregistered authors:</p> - <ul> - {% for author_unreg in publication.authors_unregistered.all %} - <li> - <a href="{% url 'journals:mark_first_author_unregistered' publication_id=publication.id unregistered_author_id=author_unreg.id %}">{{ author_unreg }}</a> - </li> - {% endfor %} - </ul> - </div> - </div> + <li> + Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }}{% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %}) + <ul class="list-unstyled pl-4"> + {% for author in publication.authors.all %} + <li> + {{ author.order }}. <a href="{% url 'journals:mark_first_author' publication_id=publication.id author_object_id=author.id %}">{{ author }}</a> + </li> + {% endfor %} + </ul> </li> <li><a href="{% url 'journals:add_author' publication.id %}">Add a missing author</a></li> <li><a href="{% url 'journals:create_citation_list_metadata' publication.doi_label %}">Create/update citation list metadata</a></li> diff --git a/journals/urls/general.py b/journals/urls/general.py index dd9cfea9eab02f3c9e99417c5d25887fd7b75956..c57c961fd9e4985efee6e2e2b7fc310190e2547c 100644 --- a/journals/urls/general.py +++ b/journals/urls/general.py @@ -23,24 +23,15 @@ urlpatterns = [ url(r'^validate_publication$', journals_views.validate_publication, name='validate_publication'), - url(r'^mark_first_author/(?P<publication_id>[0-9]+)/(?P<contributor_id>[0-9]+)$', + url(r'^mark_first_author/(?P<publication_id>[0-9]+)/(?P<author_object_id>[0-9]+)$', journals_views.mark_first_author, name='mark_first_author'), - url(r'^mark_first_author_unregistered/(?P<publication_id>[0-9]+)/(?P<unregistered_author_id>[0-9]+)$', - journals_views.mark_first_author_unregistered, - name='mark_first_author_unregistered'), url(r'^add_author/(?P<publication_id>[0-9]+)/(?P<contributor_id>[0-9]+)$', journals_views.add_author, name='add_author'), url(r'^add_author/(?P<publication_id>[0-9]+)$', journals_views.add_author, name='add_author'), - url(r'^add_unregistered_author/(?P<publication_id>[0-9]+)/(?P<unregistered_author_id>[0-9]+)$', - journals_views.add_unregistered_author, - name='add_unregistered_author'), - url(r'^add_new_unreg_author/(?P<publication_id>[0-9]+)$', - journals_views.add_new_unreg_author, - name='add_new_unreg_author'), url(r'^manage_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', journals_views.manage_metadata, name='manage_metadata'), diff --git a/journals/views.py b/journals/views.py index 54ffe22a2c4f8cf5ee6e4e344f574192db084b2d..2456765e8afcf0601a8725e8b6efbec92db10d3d 100644 --- a/journals/views.py +++ b/journals/views.py @@ -21,8 +21,8 @@ from django.shortcuts import get_object_or_404, render, redirect from .exceptions import PaperNumberingError from .helpers import paper_nr_string, issue_doi_label_from_doi_label -from .models import Journal, Issue, Publication, UnregisteredAuthor, Deposit, DOAJDeposit,\ - GenericDOIDeposit +from .models import Journal, Issue, Publication, Deposit, DOAJDeposit,\ + GenericDOIDeposit, PublicationAuthorsTable from .forms import FundingInfoForm, InitiatePublicationForm, ValidatePublicationForm,\ UnregisteredAuthorForm, CreateMetadataXMLForm, CitationListBibitemsForm,\ ReferenceFormSet @@ -246,18 +246,22 @@ def validate_publication(request): if validate_publication_form.is_valid(): publication = validate_publication_form.save() - # Fill in remaining data + # Fill remaining data submission = publication.accepted_submission - publication.authors.add(*submission.authors.all()) - if publication.first_author: - publication.authors.add(publication.first_author) if publication.first_author_unregistered: - publication.authors_unregistered.add(publication.first_author_unregistered) + PublicationAuthorsTable.objects.create( + order=1, + publication=publication, + unregistered_author=publication.first_author_unregistered) + + for submission_author in submission.authors.all(): + PublicationAuthorsTable.objects.create( + publication=publication, contributor=submission_author) publication.authors_claims.add(*submission.authors_claims.all()) publication.authors_false_claims.add(*submission.authors_false_claims.all()) # Add Institutions to the publication - for author in publication.authors.all(): + for author in publication.authors_registered.all(): for current_affiliation in author.affiliations.active(): publication.institutions.add(current_affiliation.institution) @@ -334,25 +338,29 @@ def manage_metadata(request, issue_doi_label=None, doi_label=None): @permission_required('scipost.can_publish_accepted_submission', return_403=True) -@transaction.atomic -def mark_first_author(request, publication_id, contributor_id): +def mark_first_author(request, publication_id, author_object_id): publication = get_object_or_404(Publication, id=publication_id) - contributor = get_object_or_404(Contributor, id=contributor_id) - publication.first_author = contributor - publication.first_author_unregistered = None - publication.save() - return redirect(reverse('journals:manage_metadata', - kwargs={'doi_label': publication.doi_label})) - + author_object = get_object_or_404(publication.authors, id=author_object_id) -@permission_required('scipost.can_publish_accepted_submission', return_403=True) -@transaction.atomic -def mark_first_author_unregistered(request, publication_id, unregistered_author_id): - publication = get_object_or_404(Publication, id=publication_id) - unregistered_author = get_object_or_404(UnregisteredAuthor, id=unregistered_author_id) - publication.first_author = None - publication.first_author_unregistered = unregistered_author + # Save explicit relation + if author_object.is_registered: + publication.first_author = author_object.contributor + publication.first_author_unregistered = None + else: + publication.first_author = None + publication.first_author_unregistered = author_object.unregistered_author publication.save() + + # Redo ordering + author_object.order = 1 + author_object.save() + author_objects = publication.authors.exclude(id=author_object.id) + count = 2 + for author in author_objects: + author.order = count + author.save() + count += 1 + messages.success(request, 'Marked {} first author'.format(author_object)) return redirect(reverse('journals:manage_metadata', kwargs={'doi_label': publication.doi_label})) @@ -369,62 +377,37 @@ def add_author(request, publication_id, contributor_id=None, unregistered_author publication = get_object_or_404(Publication, id=publication_id) if contributor_id: contributor = get_object_or_404(Contributor, id=contributor_id) - publication.authors.add(contributor) + PublicationAuthorsTable.objects.create(contributor=contributor, publication=publication) publication.save() + messages.success(request, 'Added {} as an author.'.format(contributor)) return redirect(reverse('journals:manage_metadata', kwargs={'doi_label': publication.doi_label})) - if request.method == 'POST': - form = UnregisteredAuthorForm(request.POST) - if form.is_valid(): - contributors_found = Contributor.objects.filter( - user__last_name__icontains=form.cleaned_data['last_name']) - unregistered_authors_found = UnregisteredAuthor.objects.filter( - last_name__icontains=form.cleaned_data['last_name']) - new_unreg_author_form = UnregisteredAuthorForm( - initial={'first_name': form.cleaned_data['first_name'], - 'last_name': form.cleaned_data['last_name'], }) - else: - errormessage = 'Please fill in the form properly' - return render(request, 'scipost/error.html', context={'errormessage': errormessage}) - else: - form = UnregisteredAuthorForm() - contributors_found = None - unregistered_authors_found = None - new_unreg_author_form = UnregisteredAuthorForm() - context = {'publication': publication, - 'contributors_found': contributors_found, - 'unregistered_authors_found': unregistered_authors_found, - 'form': form, - 'new_unreg_author_form': new_unreg_author_form, } + contributors_found = None + form = UnregisteredAuthorForm(request.POST or request.GET or None) + + if request.POST and form.is_valid(): + unregistered_author = form.save() + PublicationAuthorsTable.objects.create( + publication=publication, + unregistered_author=unregistered_author) + messages.success(request, 'Added {} as an unregistered author.'.format( + unregistered_author + )) + return redirect(reverse('journals:manage_metadata', + kwargs={'doi_label': publication.doi_label})) + elif form.is_valid(): + contributors_found = Contributor.objects.filter( + # user__first_name__icontains=form.cleaned_data['first_name'], + user__last_name__icontains=form.cleaned_data['last_name']) + context = { + 'publication': publication, + 'contributors_found': contributors_found, + 'form': form, + } return render(request, 'journals/add_author.html', context) -@permission_required('scipost.can_publish_accepted_submission', return_403=True) -@transaction.atomic -def add_unregistered_author(request, publication_id, unregistered_author_id): - publication = get_object_or_404(Publication, id=publication_id) - unregistered_author = get_object_or_404(UnregisteredAuthor, id=unregistered_author_id) - publication.authors_unregistered.add(unregistered_author) - publication.save() - return redirect(reverse('journals:manage_metadata', - kwargs={'doi_label': publication.doi_label})) - - -@permission_required('scipost.can_publish_accepted_submission', return_403=True) -@transaction.atomic -def add_new_unreg_author(request, publication_id): - publication = get_object_or_404(Publication, id=publication_id) - if request.method == 'POST': - new_unreg_author_form = UnregisteredAuthorForm(request.POST) - if new_unreg_author_form.is_valid(): - new_unreg_author = new_unreg_author_form.save() - publication.authors_unregistered.add(new_unreg_author) - return redirect(reverse('journals:manage_metadata', - kwargs={'doi_label': publication.doi_label})) - raise Http404 - - @permission_required('scipost.can_publish_accepted_submission', return_403=True) @transaction.atomic def create_citation_list_metadata(request, doi_label): @@ -611,40 +594,27 @@ def create_metadata_xml(request, doi_label): '</journal_issue>\n' '<journal_article publication_type=\'full_text\'>\n' '<titles><title>' + publication.title + '</title></titles>\n' - '<contributors>\n' ) # Precondition: all authors MUST be listed in authors field of publication instance, # this to be checked by EdAdmin before publishing. - for author in publication.authors.all(): - if author == publication.first_author: + initial['metadata_xml'] += '<contributors>\n' + for author_object in publication.authors.all(): + if author_object.order == 1: initial['metadata_xml'] += ( '<person_name sequence=\'first\' contributor_role=\'author\'> ' - '<given_name>' + author.user.first_name + '</given_name> ' - '<surname>' + author.user.last_name + '</surname> ' + '<given_name>' + author_object.first_name + '</given_name> ' + '<surname>' + author_object.last_name + '</surname> ' ) else: initial['metadata_xml'] += ( '<person_name sequence=\'additional\' contributor_role=\'author\'> ' - '<given_name>' + author.user.first_name + '</given_name> ' - '<surname>' + author.user.last_name + '</surname> ' - ) - if author.orcid_id: - initial['metadata_xml'] += '<ORCID>http://orcid.org/' + author.orcid_id + '</ORCID>' - initial['metadata_xml'] += '</person_name>\n' - - for author_unreg in publication.authors_unregistered.all(): - if author_unreg == publication.first_author_unregistered: - initial['metadata_xml'] += ( - '<person_name sequence=\'first\' contributor_role=\'author\'> ' - '<given_name>' + author_unreg.first_name + '</given_name> ' - '<surname>' + author_unreg.last_name + '</surname> ' + '<given_name>' + author_object.first_name + '</given_name> ' + '<surname>' + author_object.last_name + '</surname> ' ) - else: + if author_object.contributor and author_object.contributor.orcid_id: initial['metadata_xml'] += ( - '<person_name sequence=\'additional\' contributor_role=\'author\'> ' - '<given_name>' + author_unreg.first_name + '</given_name> ' - '<surname>' + author_unreg.last_name + '</surname> ' + '<ORCID>http://orcid.org/' + author_object.contributor.orcid_id + '</ORCID>' ) initial['metadata_xml'] += '</person_name>\n' initial['metadata_xml'] += '</contributors>\n' diff --git a/scipost/forms.py b/scipost/forms.py index a1a08bda2e0d99bb84cc688d700543c0327ff12b..60c748382e617c1bc3a971b3caefdddb3ebb3f63 100644 --- a/scipost/forms.py +++ b/scipost/forms.py @@ -121,7 +121,7 @@ class RegistrationForm(forms.Form): country=self.cleaned_data['country_of_employment'], name=self.cleaned_data['affiliation'], ) - contributor, new = Contributor.objects.get_or_create(**{ + contributor, __ = Contributor.objects.get_or_create(**{ 'user': user, 'invitation_key': self.cleaned_data.get('invitation_key', ''), 'title': self.cleaned_data['title'], @@ -133,10 +133,6 @@ class RegistrationForm(forms.Form): contributor=contributor, institution=institution, ) - - if contributor.activation_key == '': - # Seems redundant? - contributor.generate_key() contributor.save() return contributor @@ -190,20 +186,27 @@ class DraftInvitationForm(forms.ModelForm): class ContributorsFilterForm(forms.Form): names = forms.CharField(widget=forms.Textarea()) + include_invitations = forms.BooleanField(required=False, initial=True, + label='Include invitations in the filter.') def filter(self): names_found = [] names_not_found = [] + invitations_found = [] r = self.cleaned_data['names'].replace('\r', '\n').split('\n') + include_invitations = self.cleaned_data.get('include_invitations', False) for name in r: last_name = name.split(',')[0] if not last_name: continue if Contributor.objects.filter(user__last_name__istartswith=last_name).exists(): names_found.append(name) + elif include_invitations and RegistrationInvitation.objects.pending_response().filter( + last_name__istartswith=last_name).exists(): + invitations_found.append(name) else: names_not_found.append(name) - return names_found, names_not_found + return names_found, names_not_found, invitations_found class RegistrationInvitationForm(forms.ModelForm): @@ -317,7 +320,7 @@ class UpdatePersonalDataForm(forms.ModelForm): and changes the orcid_id. It marks all Publications, Reports and Comments authors by this Contributor with a deposit_requires_update == True. """ - publications = Publication.objects.filter(authors=self.instance) + publications = Publication.objects.filter(authors_registered=self.instance) for publication in publications: publication.doideposit_needs_updating = True publication.save() diff --git a/scipost/managers.py b/scipost/managers.py index fcb78b3d9878180c70042b4b90f19e7a29206966..db457fd9bd20d2ea05fafc34f92021b5f50d5740 100644 --- a/scipost/managers.py +++ b/scipost/managers.py @@ -49,6 +49,9 @@ class RegistrationInvitationManager(models.Manager): def declined(self): return self.filter(responded=True, declined=True) + def pending_response(self): + return self.filter(responded=False) + def declined_or_without_response(self): return self.filter(Q(responded=True, declined=True) | Q(responded=False)) diff --git a/scipost/migrations/0003_auto_20180206_1940.py b/scipost/migrations/0003_auto_20180206_1940.py new file mode 100644 index 0000000000000000000000000000000000000000..49b00fcebc59e03bb54e71967c6c4965b2fa43d5 --- /dev/null +++ b/scipost/migrations/0003_auto_20180206_1940.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-02-06 18:40 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('scipost', '0002_auto_20171229_1435'), + ] + + operations = [ + migrations.AlterField( + model_name='contributor', + name='user', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/scipost/migrations/0004_auto_20180212_1932.py b/scipost/migrations/0004_auto_20180212_1932.py new file mode 100644 index 0000000000000000000000000000000000000000..f7e69e16c0bd73c4f52dec139d09ff200360a64a --- /dev/null +++ b/scipost/migrations/0004_auto_20180212_1932.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-02-12 18:32 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('scipost', '0003_auto_20180206_1940'), + ] + + operations = [ + migrations.AlterField( + model_name='contributor', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/scipost/models.py b/scipost/models.py index 03121a51bf68120856deb74203694cd5482c2fd3..b217d78e78b1c207bbb7cb6aab19ae709dc0438d 100644 --- a/scipost/models.py +++ b/scipost/models.py @@ -4,7 +4,8 @@ import random import string from django.core.urlresolvers import reverse -from django.contrib.auth.models import User +from django.conf import settings +from django.contrib.auth import get_user_model from django.contrib.postgres.fields import ArrayField from django.db import models from django.utils import timezone @@ -14,7 +15,8 @@ from .constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS,\ subject_areas_dict, CONTRIBUTOR_STATUS, TITLE_CHOICES,\ INVITATION_STYLE, INVITATION_TYPE,\ INVITATION_CONTRIBUTOR, INVITATION_FORMAL,\ - AUTHORSHIP_CLAIM_PENDING, AUTHORSHIP_CLAIM_STATUS + AUTHORSHIP_CLAIM_PENDING, AUTHORSHIP_CLAIM_STATUS,\ + CONTRIBUTOR_NEWLY_REGISTERED from .fields import ChoiceArrayField from .managers import FellowManager, ContributorQuerySet, RegistrationInvitationManager,\ UnavailabilityPeriodManager, AuthorshipClaimQuerySet @@ -28,7 +30,7 @@ def get_sentinel_user(): status: "deactivated" and anonymized. Fallback user for models relying on Contributor that is being deleted. ''' - user, new = User.objects.get_or_create(username='deleted') + user, __ = get_user_model().objects.get_or_create(username='deleted') return Contributor.objects.get_or_create(status=-4, user=user)[0] @@ -37,11 +39,12 @@ class Contributor(models.Model): All *science* users of SciPost are Contributors. username, password, email, first_name and last_name are inherited from User. """ - user = models.OneToOneField(User, on_delete=models.PROTECT, unique=True) + user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, unique=True) invitation_key = models.CharField(max_length=40, blank=True) activation_key = models.CharField(max_length=40, blank=True) key_expires = models.DateTimeField(default=timezone.now) - status = models.SmallIntegerField(default=0, choices=CONTRIBUTOR_STATUS) + status = models.SmallIntegerField(default=CONTRIBUTOR_NEWLY_REGISTERED, + choices=CONTRIBUTOR_STATUS) title = models.CharField(max_length=4, choices=TITLE_CHOICES) discipline = models.CharField(max_length=20, choices=SCIPOST_DISCIPLINES, default='physics', verbose_name='Main discipline') @@ -69,7 +72,7 @@ class Contributor(models.Model): def save(self, *args, **kwargs): if not self.activation_key: self.generate_key() - super().save(*args, **kwargs) + return super().save(*args, **kwargs) def get_absolute_url(self): return reverse('scipost:contributor_info', args=(self.id,)) diff --git a/scipost/templates/scipost/contributors_filter.html b/scipost/templates/scipost/contributors_filter.html index eedc758ad56422aea9a9aeee8717b017e1f594f9..12418bd8a252a1be98829df8c4ee790cd806ce2a 100644 --- a/scipost/templates/scipost/contributors_filter.html +++ b/scipost/templates/scipost/contributors_filter.html @@ -33,13 +33,17 @@ <h2>Filter result</h2> {% if names_not_found %} <h3>New names</h3> - <pre><code>{% for name in names_not_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre> + <pre class="mb-3"><code>{% for name in names_not_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre> {% endif %} - <br> + {% if names_found %} <h3>Names found in the system</h3> - <pre><code>{% for name in names_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre> + <pre class="mb-3"><code>{% for name in names_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre> + {% endif %} + {% if invitations_found %} + <h3>Invitations (pending response) found in database</h3> + <pre class="mb-3"><code>{% for name in invitations_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre> {% endif %} {% endif %} diff --git a/scipost/views.py b/scipost/views.py index 64fd94a5749dd079d2f9ddcc32b412d874ad075c..b9d8656f910498ac50b5d7993d097c7f8b7eb00b 100644 --- a/scipost/views.py +++ b/scipost/views.py @@ -44,7 +44,7 @@ from affiliations.forms import AffiliationsFormset from colleges.permissions import fellowship_or_admin_required from commentaries.models import Commentary from comments.models import Comment -from journals.models import Publication, Journal +from journals.models import Publication, Journal, PublicationAuthorsTable from mails.views import MailEditingSubView from news.models import NewsItem from submissions.models import Submission, RefereeInvitation,\ @@ -386,17 +386,16 @@ def contributors_filter(request): view returns all entries of those lists with users that are certainly not registered or invitated. """ - names_found = names_not_found = None + names_found = names_not_found = invitations_found = None form = ContributorsFilterForm(request.POST or None) if form.is_valid(): - names_found, names_not_found = form.filter() - # messages.success(request, 'Draft invitation saved.') - # return redirect(reverse('scipost:draft_registration_invitation')) + names_found, names_not_found, invitations_found = form.filter() context = { 'form': form, 'names_found': names_found, 'names_not_found': names_not_found, + 'invitations_found': invitations_found, } return render(request, 'scipost/contributors_filter.html', context) @@ -798,7 +797,7 @@ def _personal_page_publications(request): } context['nr_publication_authorships_to_claim'] = Publication.objects.filter( author_list__contains=request.user.last_name).exclude( - authors=contributor).exclude( + authors_registered=contributor).exclude( authors_claims=contributor).exclude( authors_false_claims=contributor).count() return render(request, 'partials/scipost/personal_page/publications.html', context) @@ -1026,28 +1025,28 @@ def claim_authorships(request): contributor = Contributor.objects.get(user=request.user) publication_authorships_to_claim = (Publication.objects - .filter(author_list__contains=contributor.user.last_name) - .exclude(authors__in=[contributor]) - .exclude(authors_claims__in=[contributor]) - .exclude(authors_false_claims__in=[contributor])) + .filter(author_list__contains=contributor.user.last_name) + .exclude(authors_registered=contributor) + .exclude(authors_claims=contributor) + .exclude(authors_false_claims=contributor)) pub_auth_claim_form = AuthorshipClaimForm() submission_authorships_to_claim = (Submission.objects .filter(author_list__contains=contributor.user.last_name) - .exclude(authors__in=[contributor]) - .exclude(authors_claims__in=[contributor]) - .exclude(authors_false_claims__in=[contributor])) + .exclude(authors=contributor) + .exclude(authors_claims=contributor) + .exclude(authors_false_claims=contributor)) sub_auth_claim_form = AuthorshipClaimForm() commentary_authorships_to_claim = (Commentary.objects .filter(author_list__contains=contributor.user.last_name) - .exclude(authors__in=[contributor]) - .exclude(authors_claims__in=[contributor]) - .exclude(authors_false_claims__in=[contributor])) + .exclude(authors=contributor) + .exclude(authors_claims=contributor) + .exclude(authors_false_claims=contributor)) com_auth_claim_form = AuthorshipClaimForm() thesis_authorships_to_claim = (ThesisLink.objects .filter(author__contains=contributor.user.last_name) - .exclude(author_as_cont__in=[contributor]) - .exclude(author_claims__in=[contributor]) - .exclude(author_false_claims__in=[contributor])) + .exclude(author_as_cont=contributor) + .exclude(author_claims=contributor) + .exclude(author_false_claims=contributor)) thesis_auth_claim_form = AuthorshipClaimForm() context = { @@ -1140,16 +1139,17 @@ def vet_authorship_claim(request, claim_id, claim): vetting_contributor = Contributor.objects.get(user=request.user) claim_to_vet = AuthorshipClaim.objects.get(pk=claim_id) - if claim_to_vet.publication is not None: + if claim_to_vet.publication: claim_to_vet.publication.authors_claims.remove(claim_to_vet.claimant) if claim == '1': - claim_to_vet.publication.authors.add(claim_to_vet.claimant) + PublicationAuthorsTable.objects.create( + publication=claim_to_vet.publication, contributor=claim_to_vet.claimant) claim_to_vet.status = '1' elif claim == '0': claim_to_vet.publication.authors_false_claims.add(claim_to_vet.claimant) claim_to_vet.status = '-1' claim_to_vet.publication.save() - if claim_to_vet.submission is not None: + if claim_to_vet.submission: claim_to_vet.submission.authors_claims.remove(claim_to_vet.claimant) if claim == '1': claim_to_vet.submission.authors.add(claim_to_vet.claimant) @@ -1158,7 +1158,7 @@ def vet_authorship_claim(request, claim_id, claim): claim_to_vet.submission.authors_false_claims.add(claim_to_vet.claimant) claim_to_vet.status = '-1' claim_to_vet.submission.save() - if claim_to_vet.commentary is not None: + if claim_to_vet.commentary: claim_to_vet.commentary.authors_claims.remove(claim_to_vet.claimant) if claim == '1': claim_to_vet.commentary.authors.add(claim_to_vet.claimant) @@ -1167,7 +1167,7 @@ def vet_authorship_claim(request, claim_id, claim): claim_to_vet.commentary.authors_false_claims.add(claim_to_vet.claimant) claim_to_vet.status = '-1' claim_to_vet.commentary.save() - if claim_to_vet.thesislink is not None: + if claim_to_vet.thesislink: claim_to_vet.thesislink.author_claims.remove(claim_to_vet.claimant) if claim == '1': claim_to_vet.thesislink.author_as_cont.add(claim_to_vet.claimant) @@ -1189,7 +1189,7 @@ def contributor_info(request, contributor_id): on the relevant name (in listing headers of Submissions, ...). """ contributor = get_object_or_404(Contributor, pk=contributor_id) - contributor_publications = Publication.objects.published().filter(authors=contributor) + contributor_publications = Publication.objects.published().filter(authors_registered=contributor) contributor_submissions = Submission.objects.public_unlisted().filter(authors=contributor) contributor_commentaries = Commentary.objects.filter(authors=contributor) contributor_theses = ThesisLink.objects.vetted().filter(author_as_cont=contributor)