diff --git a/src/homework/migrations/0001_initial.py b/src/homework/migrations/0001_initial.py deleted file mode 100644 index 524ab9f6d3f30587c7cc28b3bcd15448db8b6077..0000000000000000000000000000000000000000 --- a/src/homework/migrations/0001_initial.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.5 on 2017-11-11 14:39 -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): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Solution', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('date', models.DateTimeField()), - ('ready', models.BooleanField()), - ('files', models.FileField(upload_to='')), - ], - ), - migrations.CreateModel( - name='Student', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('homework', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='homework.Solution')), - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='Task', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=150)), - ('date', models.DateTimeField()), - ('deadline', models.DateTimeField()), - ('text', models.TextField()), - ('files', models.FileField(upload_to='')), - ('author', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.AddField( - model_name='solution', - name='task', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='homework.Task'), - ), - ] diff --git a/src/homework/models.py b/src/homework/models.py index a5192a8b87bb9e57fae6d7cf35d8e08b208f3358..0ea978653e30d95254dd3b5ad4e4d4b31a8014ce 100644 --- a/src/homework/models.py +++ b/src/homework/models.py @@ -1,22 +1,63 @@ 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 . import myfields + +# 5MB - 5242880 +MAX_UPLOAD_SIZE = 5242880 + + +def validate_deadline(date): + if date <= timezone.now(): + raise ValidationError(_('Date must be greater than now'), code='invalid') + + +# def validate_file_size(file): +# if file._size > MAX_UPLOAD_SIZE: +# raise ValidationError(_('Please keep filesize under' + MAX_UPLOAD_SIZE)) + class Task(models.Model): title = models.CharField(max_length=150) - date = models.DateTimeField() - deadline = models.DateTimeField() + date = models.DateTimeField(auto_now_add=True, editable=False) + deadline = models.DateTimeField(validators=[validate_deadline]) text = models.TextField() - author = models.OneToOneField(User) - files = models.FileField() + created_by = models.ForeignKey(User) + files = models.FileField(validators=[validators.FileExtensionValidator('image/png', 'image/jpeg', 'application/zip')], + blank=True, + ) + # files = myfields.RestrictedFileField( + # content_types=['image/png', 'image/jpeg', 'application/zip'], + # max_upload_size=MAX_UPLOAD_SIZE, + # blank=True, + # null=True, + # ) +# solution_file = models.BooleanField() +# +# + # def deadline_clean(self): + # if self.deadline <= timezone.now(): + # raise ValidationError(_('Invalid date'), code='invalid') -# NormĂĄlisabb angol nevet adni ĂŠr!! class Solution(models.Model): - task = models.ForeignKey(Task, on_delete=models.CASCADE) - date = models.DateTimeField() + task = models.ForeignKey(Task, on_delete=models.CASCADE,) + date = models.DateTimeField(auto_now_add=True, editable=False) ready = models.BooleanField() - files = models.FileField() + files = models.FileField(validators=[ + validators.FileExtensionValidator('image/png', 'image/jpeg', 'application/zip')], + blank=True, + ) + created_by = models.ForeignKey(User) + # files = myfields.RestrictedFileField( + # content_types=['image/png', 'image/jpeg', 'application/zip'], + # max_upload_size=MAX_UPLOAD_SIZE, + # blank=True, + # ) class Student(models.Model): diff --git a/src/homework/myfields.py b/src/homework/myfields.py new file mode 100644 index 0000000000000000000000000000000000000000..c343daa73b1aa8407ad21dfdab6f997d51c2a021 --- /dev/null +++ b/src/homework/myfields.py @@ -0,0 +1,41 @@ +from django import forms +from django.template.defaultfilters import filesizeformat +from django.utils.translation import ugettext_lazy as _ +from django.core.exceptions import ValidationError + + +class RestrictedFileField(forms.FileField): + """ + Same as FileField, but you can specify: + * content_types - list containing allowed content_types. Example: ['application/pdf', 'image/jpeg'] + * max_upload_size - a number indicating the maximum file size allowed for upload. + 2.5MB - 2621440 + 5MB - 5242880 + 10MB - 10485760 + 20MB - 20971520 + 50MB - 5242880 + 100MB - 104857600 + 250MB - 214958080 + 500MB - 429916160 +""" + + def __init__(self, *args, **kwargs): + self.content_types = kwargs.pop("content_types") + self.max_upload_size = kwargs.pop("max_upload_size") + super().__init__(*args, **kwargs) + + def clean(self, data, initial=None): + file = super().clean(data, initial) + + try: + content_type = file.content_type + if content_type in self.content_types: + if file._size > self.max_upload_size: + raise ValidationError(_('Please keep filesize under %s. Current filesize %s') % ( + filesizeformat(self.max_upload_size), filesizeformat(file._size))) + else: + raise ValidationError(_('Filetype not supported.')) + except AttributeError: + pass + + return data diff --git a/src/homework/permissions.py b/src/homework/permissions.py new file mode 100644 index 0000000000000000000000000000000000000000..190743e7269715043e31f591240efb4fab77c2ec --- /dev/null +++ b/src/homework/permissions.py @@ -0,0 +1,28 @@ +from rest_framework.permissions import BasePermission +from rest_framework.permissions import SAFE_METHODS + + +class IsStaffOrReadOnly(BasePermission): + """ + The request is authenticated as a staff, or is a read-only request. + """ + + def has_permission(self, request, view): + return ( + request.method in SAFE_METHODS or + request.user and + request.user.is_staff + ) + + +class IsAuthenticatedOrReadOnly(BasePermission): + """ + The request is authenticated as a user, or is a read-only request. + """ + + def has_permission(self, request, view): + return ( + request.method in SAFE_METHODS or + request.user and + request.user.is_authenticated + ) diff --git a/src/homework/serializers.py b/src/homework/serializers.py index 3e2500d68884b532f7624310bab1f54bf5615140..4ca1c9a52c6122926751602a53571ad23fbcc7e1 100644 --- a/src/homework/serializers.py +++ b/src/homework/serializers.py @@ -6,12 +6,16 @@ class TaskSerializer(serializers.ModelSerializer): class Meta: model = models.Task fields = '__all__' + read_only_fields = ('created_by', 'date') + extra_kwargs = {'created_by': {'default': serializers.CurrentUserDefault()}} class SolutionSerializer(serializers.ModelSerializer): class Meta: model = models.Solution fields = '__all__' + read_only_fields = ('created_by', 'date') + extra_kwargs = {'created_by': {'default': serializers.CurrentUserDefault()}} class StudentSerializer(serializers.ModelSerializer): diff --git a/src/homework/views.py b/src/homework/views.py index d3429a7528e1c87a33309a7d4e1935a2d12d2faa..548bab0f4ad5d5244e8ba5f2d0585ae36bd9c062 100644 --- a/src/homework/views.py +++ b/src/homework/views.py @@ -1,19 +1,24 @@ from rest_framework import viewsets + from . import serializers from . import models +from . import permissions class TasksViewSet(viewsets.ModelViewSet): serializer_class = serializers.TaskSerializer queryset = models.Task.objects.all() + permission_classes = (permissions.IsStaffOrReadOnly,) class SolutionViewSet(viewsets.ModelViewSet): serializer_class = serializers.SolutionSerializer queryset = models.Solution.objects.all() + #permission_classes = () class StudentViewSet(viewsets.ModelViewSet): serializer_class = serializers.StudentSerializer queryset = models.Student.objects.all() +