-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharticles.py
More file actions
109 lines (93 loc) · 3.41 KB
/
articles.py
File metadata and controls
109 lines (93 loc) · 3.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
from jdhapi.models import Article
from jdhapi.serializers.article import ArticleSerializer
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, filters
from rest_framework.permissions import BasePermission
from django.shortcuts import get_object_or_404
from jdhapi.views.articles.status_handlers import *
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAdminUser
class IsOwnerFilterBackend(filters.BaseFilterBackend):
"""
Filter that only allows users to see their own objects.
"""
def filter_queryset(self, request, queryset, view):
if request.user.is_staff:
return queryset # Staff members can see all articles
else:
return queryset.filter(status=Article.Status.PUBLISHED)
class IsAuthenticatedForNonPublished(BasePermission):
"""
Custom permission to allow only authenticated users to access non-published articles.
"""
def has_object_permission(self, request, view, obj):
if obj.status == Article.Status.PUBLISHED:
return True
return request.user.is_authenticated
class ArticleList(generics.ListCreateAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
filter_backends = [
IsOwnerFilterBackend,
DjangoFilterBackend,
filters.OrderingFilter,
filters.SearchFilter,
]
filterset_fields = [
"issue",
"abstract",
"status",
"tags",
"authors",
"copyright_type",
"abstract__callpaper",
]
ordering_fields = [
"issue__publication_date",
"publication_date",
"abstract__title",
"abstract__pid",
]
ordering = ["-issue__publication_date", "-publication_date"]
search_fields = [
"abstract__title",
"abstract__pid",
"abstract__contact_lastname",
"abstract__contact_firstname",
]
def get_queryset(self):
"""
Optionally restricts the returned articles to a given issue,
by filtering against a `pid` query parameter in the URL.
"""
queryset = super().get_queryset()
pid = self.request.query_params.get("pid")
if pid is not None:
queryset = queryset.filter(issue__pid=pid)
return queryset
def filter_queryset(self, queryset):
# Apply DRF filters
qs = super().filter_queryset(queryset)
return qs
class ArticleDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [IsAuthenticatedForNonPublished]
queryset = Article.objects.all()
serializer_class = ArticleSerializer
lookup_field = "abstract__pid"
class ArticleStatus(APIView):
permission_classes = [IsAdminUser]
STATUS_HANDLERS = {
'TECHNICAL_REVIEW': TechnicalReviewHandler(),
'COPY_EDITING': CopyEditingHandler(),
'PEER_REVIEW': PeerReviewHandler(),
'PUBLISHED' : PublishedHandler()
}
def patch(self, request, abstract__pid):
article = get_object_or_404(Article, abstract__pid=abstract__pid)
new_status = request.data.get('status')
handler = self.STATUS_HANDLERS.get(new_status)
if handler:
return handler.handle(article, request)
return Response({"error": "Invalid status"}, status=400)