diff --git a/src/common/serializers.py b/src/common/serializers.py new file mode 100644 index 0000000000000000000000000000000000000000..5e088623aa7d51eb2bdb7d73bec6d22a6e8777ce --- /dev/null +++ b/src/common/serializers.py @@ -0,0 +1,12 @@ +from rest_framework import compat + + +class CurrentUserProfileDefault(object): + def set_context(self, serializer_field): + self.user = serializer_field.context['request'].user + + def __call__(self): + return self.user.profile + + def __repr__(self): + return compat.unicode_to_repr('%s()' % self.__class__.__name__) diff --git a/src/common/validators.py b/src/common/validators.py new file mode 100644 index 0000000000000000000000000000000000000000..343f781994180b3c1cdaa3c35a6607d31cb527de --- /dev/null +++ b/src/common/validators.py @@ -0,0 +1,26 @@ +from django.core import exceptions +from django.utils.deconstruct import deconstructible +from django.utils.translation import ugettext_lazy as _ + + +@deconstructible +class FileSizeValidator(): + size_limit = 5242880 # 5MB - 5242880 + message = _('Too big file. %(size)d') + code = 'invalid' + + def __init__(self, size_limit=None, message=None, code=None): + if size_limit is not None: + self.size_limit = size_limit + if message is not None: + self.message = message + if code is not None: + self.code = code + + def __call__(self, file): + if file.size > self.size_limit: + raise exceptions.ValidationError( + self.message, + code=self.code, + params={'size': file.size} + ) diff --git a/src/homework/migrations/0001_initial.py b/src/homework/migrations/0001_initial.py index 57b9c1f5cea623dae04423523f427ff85e27bdc3..c06eb4269e2b206e70b8f7514767233c7345ca2b 100644 --- a/src/homework/migrations/0001_initial.py +++ b/src/homework/migrations/0001_initial.py @@ -42,7 +42,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=150)), ('date', models.DateTimeField(auto_now_add=True)), - ('deadline', models.DateTimeField(validators=[homework.models.validate_deadline])), + ('deadline', models.DateTimeField()), ('text', models.TextField()), ('files', models.FileField(blank=True, upload_to='', validators=[django.core.validators.FileExtensionValidator('image/png', 'image/jpeg', 'application/zip')])), ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), diff --git a/src/homework/migrations/0009_merge_20180404_0825.py b/src/homework/migrations/0009_merge_20180404_0825.py new file mode 100644 index 0000000000000000000000000000000000000000..f571560b1b4a742a700c4cc132ec54dfcca51d1f --- /dev/null +++ b/src/homework/migrations/0009_merge_20180404_0825.py @@ -0,0 +1,14 @@ +# Generated by Django 2.0.1 on 2018-04-04 06:25 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('homework', '0008_auto_20180221_1135'), + ('homework', '0007_merge_20180205_2021'), + ] + + operations = [ + ] diff --git a/src/homework/migrations/0010_auto_20180404_0828.py b/src/homework/migrations/0010_auto_20180404_0828.py new file mode 100644 index 0000000000000000000000000000000000000000..5be35ff4d7666d295858224239b0a23465f51d6a --- /dev/null +++ b/src/homework/migrations/0010_auto_20180404_0828.py @@ -0,0 +1,30 @@ +# Generated by Django 2.0.1 on 2018-04-04 06:28 + +import common.validators +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('homework', '0009_merge_20180404_0825'), + ] + + operations = [ + migrations.AlterField( + model_name='solution', + name='files', + field=models.FileField(blank=True, upload_to='', validators=[django.core.validators.FileExtensionValidator('image/png', 'image/jpeg', 'application/zip'), common.validators.FileSizeValidator(size_limit=52428800)]), + ), + migrations.AlterField( + model_name='task', + name='deadline', + field=models.DateTimeField(), + ), + migrations.AlterField( + model_name='task', + name='files', + field=models.FileField(blank=True, upload_to='', validators=[django.core.validators.FileExtensionValidator('image/png', 'image/jpeg', 'application/zip'), common.validators.FileSizeValidator(size_limit=52428800)]), + ), + ] diff --git a/src/homework/migrations/0011_auto_20180404_0853.py b/src/homework/migrations/0011_auto_20180404_0853.py new file mode 100644 index 0000000000000000000000000000000000000000..0524fa088229ac404951a80687b7ff5f998c0b42 --- /dev/null +++ b/src/homework/migrations/0011_auto_20180404_0853.py @@ -0,0 +1,25 @@ +# Generated by Django 2.0.1 on 2018-04-04 06:53 + +import common.validators +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('homework', '0010_auto_20180404_0828'), + ] + + operations = [ + migrations.AlterField( + model_name='solution', + name='files', + field=models.FileField(blank=True, upload_to='', validators=[django.core.validators.FileExtensionValidator(['image/png', 'image/jpeg', 'application/zip']), common.validators.FileSizeValidator(size_limit=52428800)]), + ), + migrations.AlterField( + model_name='task', + name='files', + field=models.FileField(blank=True, upload_to='', validators=[django.core.validators.FileExtensionValidator(['image/png', 'image/jpeg', 'application/zip']), common.validators.FileSizeValidator(size_limit=52428800)]), + ), + ] diff --git a/src/homework/models.py b/src/homework/models.py index 5974d6bbbfc4fa0cbfa108e887598c43c4028d15..c586fa0e4bcc15e2d0f05e08a212efc7dd7366c8 100644 --- a/src/homework/models.py +++ b/src/homework/models.py @@ -1,34 +1,25 @@ from django.db import models -from django.contrib.auth.models import User -from django.core.exceptions import ValidationError -from django.utils.translation import ugettext_lazy as _ -from django.utils import timezone from django.core import validators -from account.models import Profile -# from . import myfields - - -# 5MB - 5242880 -__MAX_UPLOAD_SIZE = 5242880 - -def validate_deadline(deadline): - if deadline <= timezone.now(): - raise ValidationError(_('Date must be greater than now'), code='invalid') +from common.validators import FileSizeValidator +from account.models import Profile class Task(models.Model): title = models.CharField(max_length=150) date = models.DateTimeField(auto_now_add=True, editable=False) - deadline = models.DateTimeField(validators=[validate_deadline]) + deadline = models.DateTimeField() text = models.TextField() created_by = models.ForeignKey(Profile, on_delete=models.DO_NOTHING) files = models.FileField( - validators=[validators.FileExtensionValidator( - 'image/png', - 'image/jpeg', - 'application/zip', - )], + validators=[ + validators.FileExtensionValidator([ + 'image/png', + 'image/jpeg', + 'application/zip', + ]), + FileSizeValidator(size_limit=52428800), # 52428800 - 50MiB + ], blank=True, ) @@ -38,15 +29,18 @@ class Task(models.Model): class Solution(models.Model): task = models.ForeignKey(Task, related_name='task_solution', on_delete=models.CASCADE) - created_by = models.ForeignKey(Profile, related_name='student_solution', on_delete=models.CASCADE) + created_by = models.ForeignKey(Profile, related_name='student_solution', on_delete=models.CASCADE) date = models.DateTimeField(auto_now_add=True, editable=False) ready = models.BooleanField(default=False) accepted = models.BooleanField(default=False) files = models.FileField( - validators=[validators.FileExtensionValidator( - 'image/png', - 'image/jpeg', - 'application/zip', - )], + validators=[ + validators.FileExtensionValidator([ + 'image/png', + 'image/jpeg', + 'zip', + ]), + FileSizeValidator(size_limit=52428800), # 52428800 - 50MiB + ], blank=True, ) diff --git a/src/homework/serializers.py b/src/homework/serializers.py index f3a816eca87897f29294a444425ada034a3ef314..5b5497f42d329568cc83a72337262d5c4acd8fff 100644 --- a/src/homework/serializers.py +++ b/src/homework/serializers.py @@ -1,29 +1,23 @@ from rest_framework import serializers + +from common.serializers import CurrentUserProfileDefault from . import models class TaskSerializer(serializers.ModelSerializer): + created_by = serializers.HiddenField(default=CurrentUserProfileDefault()) + class Meta: model = models.Task read_only_fields = ('created_by', 'date') - # extra_kwargs = {'created_by': {'default': serializers.CurrentUserDefault()}} fields = '__all__' class SolutionSerializer(serializers.ModelSerializer): date = serializers.DateTimeField(read_only=True) + created_by = serializers.HiddenField(default=CurrentUserProfileDefault()) class Meta: model = models.Solution read_only_fields = ('created_by', 'date' 'ready') - # extra_kwargs = {'created_by': {'default': serializers.CurrentUserDefault()}} fields = ('task', 'date', 'accepted', 'files', 'created_by') - - # def validate(self, attrs): - # task = attrs['task'] - # date = attrs['date'] keyerror - # - # if task.deadline < date: - # raise serializers.ValidationError("You cannot submit homework after the deadline") - # - # return attrs diff --git a/src/homework/views.py b/src/homework/views.py index c6f1f9bdd84ef2f3c208a4a9733af6888c7e4265..508a498316ebe68f0057926201b7c055caaf9545 100644 --- a/src/homework/views.py +++ b/src/homework/views.py @@ -1,15 +1,9 @@ -from rest_framework import viewsets +from rest_framework import viewsets, status from rest_framework.response import Response -from rest_framework import status -from rest_framework.decorators import list_route -from django.http import Http404 -from django.shortcuts import get_object_or_404 -import datetime -from django.utils import timezone +from common import permissions from . import serializers from . import models -from common import permissions class TasksViewSet(viewsets.ModelViewSet): @@ -22,21 +16,3 @@ class SolutionsViewSet(viewsets.ModelViewSet): serializer_class = serializers.SolutionSerializer queryset = models.Solution.objects.all() permission_classes = (permissions.IsStaffOrReadOnlyForAuthenticated, ) - - def perform_create(self, serializer): - serializer.validated_data['accepted'] = False - task = serializer.validated_data['task'] - now = timezone.now() - if task.deadline < now: - raise Http404("Deadline") - serializer.save() - - # def get_queryset(self): - # user = self.request.user - # if user.has_perm(permissions.IsStaffUser): - # return models.Solution.objects.all() - # - # @list_route(methods=['get']) - # def me(self, request): - # serializer = self.serializer_class(request.user.profile) #request ? - # return Response(serializer.data) \ No newline at end of file