Some serialization BS

This commit is contained in:
Aarni Halinen
2020-08-04 01:04:38 +03:00
parent e03b6e6606
commit 38669947cd
7 changed files with 80 additions and 39 deletions
+1 -3
View File
@@ -127,9 +127,7 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'auditlog.middleware.AuditlogMiddleware' 'auditlog.middleware.AuditlogMiddleware'
] ]
MIDDLEWARE_CLASSES = [
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True CORS_ORIGIN_ALLOW_ALL = True
ROOT_URLCONF = 'sikweb.urls' ROOT_URLCONF = 'sikweb.urls'
+5
View File
@@ -108,6 +108,11 @@ class SignupForm(models.Model):
def signups(self): def signups(self):
return Signup.objects.filter(signupForm=self).order_by('pk') return Signup.objects.filter(signupForm=self).order_by('pk')
@property
def isOpen(self):
now = timezone.now()
return self.start_time <= now and now < self.end_time
class Meta: class Meta:
verbose_name = _('Signup form') verbose_name = _('Signup form')
verbose_name_plural = _('Signup forms') verbose_name_plural = _('Signup forms')
+19 -17
View File
@@ -7,7 +7,6 @@ class SignupSerializer(serializers.ModelSerializer):
source="signupForm", source="signupForm",
queryset=SignupForm.objects.all() queryset=SignupForm.objects.all()
) )
answer = serializers.JSONField()
list_name = serializers.CharField(read_only=True) list_name = serializers.CharField(read_only=True)
def add_extra_fields(self, validated_data): def add_extra_fields(self, validated_data):
@@ -44,8 +43,7 @@ class SignupSerializer(serializers.ModelSerializer):
} }
class SignupFormSerializer(serializers.HyperlinkedModelSerializer): class SignupFormSerializer(serializers.ModelSerializer):
questions = serializers.JSONField()
signups = serializers.SlugRelatedField( signups = serializers.SlugRelatedField(
slug_field="list_name", slug_field="list_name",
many=True, many=True,
@@ -55,36 +53,37 @@ class SignupFormSerializer(serializers.HyperlinkedModelSerializer):
class Meta: class Meta:
model = SignupForm model = SignupForm
fields = ('id', 'title', 'visible', 'start_time', 'end_time', 'questions', 'schema', 'signups', 'quota') fields = ('id', 'title', 'visible', 'isOpen', 'start_time', 'end_time', 'questions', 'schema', 'signups', 'quota')
class EventSerializer(serializers.ModelSerializer): class EventSerializer(serializers.ModelSerializer):
signupForm = SignupFormSerializer( signupForm = SignupFormSerializer(
source='filtered_signup_forms',
many=True, many=True,
read_only=True, read_only=True,
required=False,
) )
signup_id = serializers.PrimaryKeyRelatedField( signup_id = serializers.PrimaryKeyRelatedField(
many=True,
source="signupForm",
queryset=SignupForm.objects.all(), queryset=SignupForm.objects.all(),
required=False many=True,
write_only=True,
) )
tag_id = serializers.PrimaryKeyRelatedField( tag_id = serializers.PrimaryKeyRelatedField(
queryset=Tag.objects.all(),
many=True, many=True,
source="tags", write_only=True,
queryset=Tag.objects.all()
) )
class Meta: class Meta:
model = Event model = Event
fields = ('id', 'tag_id', 'tags', 'visible', 'image', 'title_fi', 'title_en', 'description_fi', 'description_en', fields = ('id', 'tag_id', 'tags', 'visible', 'image', 'title_fi', 'title_en', 'description_fi', 'description_en',
'content_fi', 'content_en', 'start_time', 'end_time', 'location', 'signup_id', 'signupForm') 'content_fi', 'content_en', 'start_time', 'end_time', 'location', 'signup_id', 'signupForm')
read_only_fields = ['tags', 'signupForm']
depth = 1 depth = 1
def create(self, validated_data): def create(self, validated_data):
signupForms = validated_data.pop('signupForm', []) signupForms = validated_data.pop('signup_id', [])
tags = validated_data.pop('tags') tags = validated_data.pop('tag_id')
event = Event.objects.create(**validated_data) event = Event.objects.create(**validated_data)
for form in signupForms: for form in signupForms:
event.signupForm.add(form) event.signupForm.add(form)
@@ -94,12 +93,15 @@ class EventSerializer(serializers.ModelSerializer):
return event return event
def update(self, instance, validated_data): def update(self, instance, validated_data):
signupForms = validated_data.pop('signupForm', []) signupForms = validated_data.pop('signup_id', [])
instance = super(EventSerializer, self).update(instance, validated_data) tags = validated_data.pop('tag_id')
instance.signupForm.clear() instance.signupForm.clear()
for form_data in signupForms: instance.tags.clear()
# form_qs = SignupForms.objects.filter(id=form['id']) for form in signupForms:
instance.signupForm.add(form_data) instance.signupForm.add(form)
for tag in tags:
instance.tags.add(tag)
instance = super(EventSerializer, self).update(instance, validated_data)
return instance return instance
+10 -4
View File
@@ -1,4 +1,4 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User, AnonymousUser
from django.utils import timezone from django.utils import timezone
from rest_framework import status from rest_framework import status
from rest_framework.test import APITestCase, APIRequestFactory from rest_framework.test import APITestCase, APIRequestFactory
@@ -57,11 +57,13 @@ class EventTestCase(APITestCase):
# Response should not have old events and invisible # Response should not have old events and invisible
self.assertEqual(len(response.data["results"]), 2) self.assertEqual(len(response.data["results"]), 2)
# Check that serialized data is equal to received response # Check that serialized data is equal to received response
req = APIRequestFactory().get(r"http://testserver/api/events/")
req.user = AnonymousUser()
expected_events = EventSerializer( expected_events = EventSerializer(
Event.objects.filter(title_fi__in=("Testitapahtuma1", "Testitapahtuma4")).order_by("start_time"), Event.objects.filter(title_fi__in=("Testitapahtuma1", "Testitapahtuma4")).order_by("start_time"),
many=True, many=True,
context={ context={
"request": APIRequestFactory().get(r"http://testserver/api/events/") "request": req
} }
) )
self.assertEqual(response.data["results"], expected_events.data) self.assertEqual(response.data["results"], expected_events.data)
@@ -71,11 +73,13 @@ class EventTestCase(APITestCase):
self.assertTrue(response.status_code, status.HTTP_200_OK) self.assertTrue(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data["results"]), 3) self.assertEqual(len(response.data["results"]), 3)
req = APIRequestFactory().get(r"http://testserver/api/events/")
req.user = AnonymousUser()
expected_events = EventSerializer( expected_events = EventSerializer(
Event.objects.filter(title_fi__in=("Testitapahtuma1", "Testitapahtuma3", "Testitapahtuma4")).order_by("start_time"), Event.objects.filter(title_fi__in=("Testitapahtuma1", "Testitapahtuma3", "Testitapahtuma4")).order_by("start_time"),
many=True, many=True,
context={ context={
"request": APIRequestFactory().get(r"http://testserver/api/events/") "request": req
} }
) )
self.assertEqual(response.data["results"], expected_events.data) self.assertEqual(response.data["results"], expected_events.data)
@@ -84,10 +88,12 @@ class EventTestCase(APITestCase):
response = self.client.get(f"{URL}{self.testEventId}/", format="json") response = self.client.get(f"{URL}{self.testEventId}/", format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
req = APIRequestFactory().get(r"http://testserver/api/events/")
req.user = AnonymousUser()
serializer = EventSerializer( serializer = EventSerializer(
Event.objects.get(title_fi="Testitapahtuma1"), Event.objects.get(title_fi="Testitapahtuma1"),
context={ context={
"request": APIRequestFactory().get(r"http://testserver/api/events/") "request": req
} }
) )
self.assertEqual(response.data, serializer.data) self.assertEqual(response.data, serializer.data)
+7
View File
@@ -49,6 +49,13 @@ class SignupTestCase(APITestCase):
self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Signup.objects.count(), 3) self.assertEqual(Signup.objects.count(), 3)
# Can signup to a hidden form
def test_create_signup_hidden(self):
new = createSignupRequest("asd", self.hiddenForm.id, ALL_QUESTION_TYPES_ANSWER)
response = self.client.post(URL, new, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Signup.objects.count(), 3)
@skip("NotImplemented") @skip("NotImplemented")
def test_get_hidden_forms_admin(self): def test_get_hidden_forms_admin(self):
pass pass
+13 -2
View File
@@ -1,3 +1,4 @@
from django.utils import timezone
from django.contrib.auth.models import User from django.contrib.auth.models import User
from unittest import skip from unittest import skip
from rest_framework import status from rest_framework import status
@@ -15,6 +16,10 @@ class SignupErrorTestCase(APITestCase):
self.signupFormRadio = createSignupForm(name="Form3", questions=[ALL_QUESTION_TYPES[1]], schema=RADIO_SCHEMA) self.signupFormRadio = createSignupForm(name="Form3", questions=[ALL_QUESTION_TYPES[1]], schema=RADIO_SCHEMA)
self.signupFormCheck = createSignupForm(name="Form4", questions=[ALL_QUESTION_TYPES[2]], schema=CBOX_SCHEMA) self.signupFormCheck = createSignupForm(name="Form4", questions=[ALL_QUESTION_TYPES[2]], schema=CBOX_SCHEMA)
self.hiddenForm = createSignupForm(visible=False) self.hiddenForm = createSignupForm(visible=False)
day_from_now = timezone.now() + timezone.timedelta(days=1)
day_before_now = timezone.now() + timezone.timedelta(days=-1)
self.signupFormNotStarted = createSignupForm(start_time=day_from_now, end_time=day_from_now)
self.signupFormEnded = createSignupForm(start_time=day_before_now, end_time=timezone.now())
self.signup1 = createSignupObject("1", self.signupForm, ALL_QUESTION_TYPES) self.signup1 = createSignupObject("1", self.signupForm, ALL_QUESTION_TYPES)
self.signup2 = createSignupObject("2", self.signupForm, ALL_QUESTION_TYPES) self.signup2 = createSignupObject("2", self.signupForm, ALL_QUESTION_TYPES)
@@ -37,8 +42,14 @@ class SignupErrorTestCase(APITestCase):
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(Signup.objects.count(), 2) self.assertEqual(Signup.objects.count(), 2)
def test_create_signup_hidden(self): def test_create_signup_not_started(self):
new = createSignupRequest("asd", self.hiddenForm.id, ALL_QUESTION_TYPES_ANSWER) new = createSignupRequest("asd", self.signupFormNotStarted.id, ALL_QUESTION_TYPES_ANSWER)
response = self.client.post(URL, new, format="json")
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(Signup.objects.count(), 2)
def test_create_signup_ended(self):
new = createSignupRequest("asd", self.signupFormEnded.id, ALL_QUESTION_TYPES_ANSWER)
response = self.client.post(URL, new, format="json") response = self.client.post(URL, new, format="json")
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(Signup.objects.count(), 2) self.assertEqual(Signup.objects.count(), 2)
+25 -13
View File
@@ -9,8 +9,10 @@ from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.views.decorators.http import require_http_methods from django.views.decorators.http import require_http_methods
from django_filters import rest_framework as filters from django_filters import rest_framework as filters
from django.db.models import Prefetch
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from rest_framework import routers, viewsets from rest_framework import routers
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticatedOrReadOnly, BasePermission, AllowAny from rest_framework.permissions import IsAuthenticatedOrReadOnly, BasePermission, AllowAny
@@ -37,7 +39,7 @@ class RootView(routers.APIRootView):
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticatedOrReadOnly]
class EventViewSet(viewsets.ModelViewSet): class EventViewSet(ModelViewSet):
queryset = Event.objects.all() queryset = Event.objects.all()
ordering = ["start_time"] ordering = ["start_time"]
serializer_class = EventSerializer serializer_class = EventSerializer
@@ -47,13 +49,23 @@ class EventViewSet(viewsets.ModelViewSet):
# search_fields = '__all__' # search_fields = '__all__'
def get_queryset(self): def get_queryset(self):
if self.request.user.is_authenticated:
if self.request.method == 'POST' or self.request.method == 'PUT':
return Event.objects.all() return Event.objects.all()
if self.request.user.is_authenticated:
return Event.objects.all().prefetch_related(
Prefetch('signupForm', queryset=SignupForm.objects.all(), to_attr='filtered_signup_forms')
)
since = self.request.query_params.get('since', None) since = self.request.query_params.get('since', None)
if since: if since:
return Event.objects.filter(visible=True, end_time__gt=since).order_by('start_time') return Event.objects.filter(visible=True, end_time__gt=since).order_by('start_time').prefetch_related(
return Event.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time') Prefetch('signupForm', queryset=SignupForm.objects.filter(visible=True), to_attr='filtered_signup_forms')
)
return Event.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time').prefetch_related(
Prefetch('signupForm', queryset=SignupForm.objects.filter(visible=True), to_attr='filtered_signup_forms')
)
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
raw_image = request.data.get("image", None) raw_image = request.data.get("image", None)
@@ -74,7 +86,7 @@ class EventViewSet(viewsets.ModelViewSet):
return super().update(request, *args, **kwargs) return super().update(request, *args, **kwargs)
class SignupFormViewSet(viewsets.ModelViewSet): class SignupFormViewSet(ModelViewSet):
queryset = SignupForm.objects.all() queryset = SignupForm.objects.all()
serializer_class = SignupFormSerializer serializer_class = SignupFormSerializer
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticatedOrReadOnly]
@@ -95,7 +107,7 @@ class SignupFormViewSet(viewsets.ModelViewSet):
return SignupForm.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time') return SignupForm.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time')
class SignupViewSet(viewsets.ModelViewSet): class SignupViewSet(ModelViewSet):
queryset = Signup.objects.all() queryset = Signup.objects.all()
serializer_class = SignupSerializer serializer_class = SignupSerializer
permission_classes = [SignupPermission] permission_classes = [SignupPermission]
@@ -116,7 +128,7 @@ class SignupViewSet(viewsets.ModelViewSet):
try: try:
answer = request.data["answer"] answer = request.data["answer"]
form = SignupForm.objects.get(id=id) form = SignupForm.objects.get(id=id)
if (form.visible): if (form.isOpen):
# Throws ValidationError if not valid # Throws ValidationError if not valid
validate(instance=answer, schema=form.schema) validate(instance=answer, schema=form.schema)
return super().create(request, *args, **kwargs) return super().create(request, *args, **kwargs)
@@ -147,13 +159,13 @@ class SignupViewSet(viewsets.ModelViewSet):
return JsonResponse(status=404, data={"error": f"SignupForm {id} not found"}) return JsonResponse(status=404, data={"error": f"SignupForm {id} not found"})
class SavedQuestionsViewSet(viewsets.ModelViewSet): class SavedQuestionsViewSet(ModelViewSet):
queryset = TemplateQuestion.objects.all() queryset = TemplateQuestion.objects.all()
serializer_class = SavedQuestionsSerializer serializer_class = SavedQuestionsSerializer
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticatedOrReadOnly]
class FeedViewSet(viewsets.ModelViewSet): class FeedViewSet(ModelViewSet):
queryset = Feed.objects.all() queryset = Feed.objects.all()
serializer_class = FeedSerializer serializer_class = FeedSerializer
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticatedOrReadOnly]
@@ -178,7 +190,7 @@ class FeedViewSet(viewsets.ModelViewSet):
return Feed.objects.filter(id__in=result_ids) return Feed.objects.filter(id__in=result_ids)
class ContactsViewSet(viewsets.ReadOnlyModelViewSet): class ContactsViewSet(ReadOnlyModelViewSet):
queryset = Occupation.objects.all() queryset = Occupation.objects.all()
serializer_class = OccupationSerializer serializer_class = OccupationSerializer
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticatedOrReadOnly]
@@ -190,13 +202,13 @@ class ContactsViewSet(viewsets.ReadOnlyModelViewSet):
return Occupation.by_year(int(year)) return Occupation.by_year(int(year))
class CommitteeViewSet(viewsets.ReadOnlyModelViewSet): class CommitteeViewSet(ReadOnlyModelViewSet):
queryset = Committee.objects.all() queryset = Committee.objects.all()
serializer_class = CommitteeSerializer serializer_class = CommitteeSerializer
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticatedOrReadOnly]
class TagsViewSet(viewsets.ReadOnlyModelViewSet): class TagsViewSet(ReadOnlyModelViewSet):
queryset = Tag.objects.all() queryset = Tag.objects.all()
serializer_class = TagSerializer serializer_class = TagSerializer
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticatedOrReadOnly]