aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps
diff options
context:
space:
mode:
authorGravatar ks129 <[email protected]>2021-02-22 08:23:04 +0200
committerGravatar ks129 <[email protected]>2021-02-22 08:23:04 +0200
commit51c57d3707c684bb908195f419e53f4ed164ba3b (patch)
tree6fe14d7598613d15d54da9ffd03351c2d9a96cc8 /pydis_site/apps
parentChange nominations serializer and add nomination entry serializer (diff)
Update nominations viewset GET and POST to make this working with 2-table system
Diffstat (limited to 'pydis_site/apps')
-rw-r--r--pydis_site/apps/api/viewsets/bot/nomination.py119
1 files changed, 96 insertions, 23 deletions
diff --git a/pydis_site/apps/api/viewsets/bot/nomination.py b/pydis_site/apps/api/viewsets/bot/nomination.py
index cf6e262f..8775515c 100644
--- a/pydis_site/apps/api/viewsets/bot/nomination.py
+++ b/pydis_site/apps/api/viewsets/bot/nomination.py
@@ -15,7 +15,8 @@ from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from pydis_site.apps.api.models.bot import Nomination
-from pydis_site.apps.api.serializers import NominationSerializer
+from pydis_site.apps.api.models.bot.nomination import NominationEntry
+from pydis_site.apps.api.serializers import NominationEntrySerializer, NominationSerializer
class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, GenericViewSet):
@@ -29,7 +30,6 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
#### Query parameters
- **active** `bool`: whether the nomination is still active
- - **actor__id** `int`: snowflake of the user who nominated the user
- **user__id** `int`: snowflake of the user who received the nomination
- **ordering** `str`: comma-separated sequence of fields to order the returned results
@@ -40,12 +40,18 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
... {
... 'id': 1,
... 'active': false,
- ... 'actor': 336843820513755157,
- ... 'reason': 'They know how to explain difficult concepts',
... 'user': 336843820513755157,
... 'inserted_at': '2019-04-25T14:02:37.775587Z',
... 'end_reason': 'They were helpered after a staff-vote',
- ... 'ended_at': '2019-04-26T15:12:22.123587Z'
+ ... 'ended_at': '2019-04-26T15:12:22.123587Z',
+ ... 'entries': [
+ ... {
+ ... 'actor': 336843820513755157,
+ ... 'reason': 'They know how to explain difficult concepts',
+ ... 'inserted_at': '2019-04-25T14:02:37.775587Z'
+ ... }
+ ... ],
+ ... 'reviewed': true
... }
... ]
@@ -59,12 +65,18 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
>>> {
... 'id': 1,
... 'active': true,
- ... 'actor': 336843820513755157,
- ... 'reason': 'They know how to explain difficult concepts',
... 'user': 336843820513755157,
... 'inserted_at': '2019-04-25T14:02:37.775587Z',
... 'end_reason': 'They were helpered after a staff-vote',
- ... 'ended_at': '2019-04-26T15:12:22.123587Z'
+ ... 'ended_at': '2019-04-26T15:12:22.123587Z',
+ ... 'entries': [
+ ... {
+ ... 'actor': 336843820513755157,
+ ... 'reason': 'They know how to explain difficult concepts',
+ ... 'inserted_at': '2019-04-25T14:02:37.775587Z'
+ ... }
+ ... ],
+ ... 'reviewed': false
... }
### Status codes
@@ -75,8 +87,9 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
Create a new, active nomination returns the created nominations.
The `user`, `reason` and `actor` fields are required and the `user`
and `actor` need to know by the site. Providing other valid fields
- is not allowed and invalid fields are ignored. A `user` is only
- allowed one active nomination at a time.
+ is not allowed and invalid fields are ignored. If `user` already have
+ active nomination, new nomination entry will be created assigned to
+ active nomination.
#### Request body
>>> {
@@ -91,7 +104,6 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
#### Status codes
- 201: returned on success
- 400: returned on failure for one of the following reasons:
- - A user already has an active nomination;
- The `user` or `actor` are unknown to the site;
- The request contained a field that cannot be set at creation.
@@ -148,10 +160,44 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
serializer_class = NominationSerializer
queryset = Nomination.objects.all()
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
- filter_fields = ('user__id', 'actor__id', 'active')
- frozen_fields = ('id', 'actor', 'inserted_at', 'user', 'ended_at')
+ filter_fields = ('user__id', 'active')
+ frozen_fields = ('id', 'inserted_at', 'user', 'ended_at')
frozen_on_create = ('ended_at', 'end_reason', 'active', 'inserted_at')
+ def list(self, request: HttpRequest, *args, **kwargs) -> Response:
+ """
+ DRF method for listing Nominations.
+
+ Called by the Django Rest Framework in response to the corresponding HTTP request.
+ """
+ queryset = self.filter_queryset(self.get_queryset())
+ data = NominationSerializer(queryset, many=True).data
+
+ for i, nomination in enumerate(data):
+ entries = NominationEntrySerializer(
+ NominationEntry.objects.filter(nomination_id=nomination["id"]),
+ many=True
+ ).data
+ data[i]["entries"] = entries
+
+ return Response(data)
+
+ def retrieve(self, request: HttpRequest, *args, **kwargs) -> Response:
+ """
+ DRF method for retrieving a Nomination.
+
+ Called by the Django Rest Framework in response to the corresponding HTTP request.
+ """
+ nomination = self.get_object()
+
+ data = NominationSerializer(nomination).data
+ data["entries"] = NominationEntrySerializer(
+ NominationEntry.objects.filter(nomination_id=nomination.id),
+ many=True
+ ).data
+
+ return Response(data)
+
def create(self, request: HttpRequest, *args, **kwargs) -> Response:
"""
DRF method for creating a Nomination.
@@ -163,19 +209,46 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
raise ValidationError({field: ['This field cannot be set at creation.']})
user_id = request.data.get("user")
- if Nomination.objects.filter(active=True, user__id=user_id).exists():
- raise ValidationError({'active': ['There can only be one active nomination.']})
+ nomination_filter = Nomination.objects.filter(active=True, user__id=user_id)
+
+ if not nomination_filter.exists():
+ serializer = NominationSerializer(
+ data=ChainMap(
+ request.data,
+ {"active": True}
+ )
+ )
+ serializer.is_valid(raise_exception=True)
+ nomination = Nomination.objects.create(**serializer.validated_data)
- serializer = self.get_serializer(
- data=ChainMap(
- request.data,
- {"active": True}
+ # Serializer truncate unnecessary data away
+ entry_serializer = NominationEntrySerializer(
+ data=ChainMap(request.data, {"nomination": nomination.id})
)
+ entry_serializer.is_valid(raise_exception=True)
+
+ entry = NominationEntry.objects.create(**entry_serializer.validated_data)
+
+ data = NominationSerializer(nomination).data
+ data["entries"] = NominationEntrySerializer([entry], many=True).data
+
+ headers = self.get_success_headers(data)
+ return Response(data, status=status.HTTP_201_CREATED, headers=headers)
+
+ entry_serializer = NominationEntrySerializer(
+ data=ChainMap(request.data, {"nomination": nomination_filter[0].id})
)
- serializer.is_valid(raise_exception=True)
- self.perform_create(serializer)
- headers = self.get_success_headers(serializer.data)
- return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
+ entry_serializer.is_valid(raise_exception=True)
+ NominationEntry.objects.create(**entry_serializer.validated_data)
+
+ data = NominationSerializer(nomination_filter[0]).data
+ data["entries"] = NominationEntrySerializer(
+ NominationEntry.objects.filter(nomination_id=nomination_filter[0].id),
+ many=True
+ ).data
+
+ headers = self.get_success_headers(data)
+ return Response(data, status=status.HTTP_201_CREATED, headers=headers)
def partial_update(self, request: HttpRequest, *args, **kwargs) -> Response:
"""