1 # -*- coding: utf-8 -*-
2 from decimal import Decimal
4 from django import forms
5 from django.core import validators
6 from django.template.defaultfilters import filesizeformat
7 from django.utils.safestring import mark_safe
9 from stage2.models import Attachment, Mark, FieldOptionSet, FieldOption
12 class AttachmentForm(forms.ModelForm):
13 assignment_id = forms.CharField(widget=forms.HiddenInput)
19 def __init__(self, assignment, file_no, label, options, *args, **kwargs):
20 prefix = 'att%s-%s' % (assignment.id, file_no)
21 super(AttachmentForm, self).__init__(*args, prefix=prefix, **kwargs)
22 self.fields['assignment_id'].initial = assignment.id
23 extensions = options.get('ext')
24 max_mb = options.get('max', 20)
25 self.max_upload_size = max_mb * 1024 * 1024
26 self.fields['file'].widget.attrs['data-max'] = max_mb
27 label_extra = ['maks. %s MB' % max_mb]
29 label_extra.append('format: %s' % ', '.join(extensions))
30 self.fields['file'].label = label + u' (%s)' % '; '.join(label_extra)
32 self.fields['file'].widget.attrs['data-ext'] = '|'.join(extensions)
33 self.extensions = extensions
36 file = self.cleaned_data['file']
37 if file.size > self.max_upload_size:
38 raise forms.ValidationError(
39 u'Prosimy o wysłanie pliku o rozmiarze najwyżej %s. Aktualny rozmiar pliku: %s' % (
40 filesizeformat(self.max_upload_size), filesizeformat(file.size)))
41 if self.extensions and ('.' not in file.name or file.name.rsplit('.', 1)[1].lower() not in self.extensions):
42 raise forms.ValidationError(u'Niepoprawne rozszerzenie, powinno być jedno z: %s' % ', '.join(self.extensions))
46 class AssignmentFieldForm(forms.Form):
47 value = forms.CharField(required=False)
48 assignment_id = forms.CharField(widget=forms.HiddenInput)
50 def __init__(self, label, field_no, options, answer, *args, **kwargs):
51 prefix = 'field%s-%s' % (answer.id, field_no)
52 super(AssignmentFieldForm, self).__init__(prefix=prefix, *args, **kwargs)
55 self.fields['value'].label = label
56 self.type = options['type']
57 self.fields['assignment_id'].initial = answer.assignment.id
58 max_length = options.get('max_length')
59 if options.get('widget') == 'area':
60 self.fields['value'].widget = forms.Textarea(attrs={'cols': 80, 'rows': 25})
62 self.fields['value'].validators.append(validators.MaxLengthValidator(int(max_length)))
63 self.fields['value'].label += u' (maks. %s znaków)' % max_length
64 self.fields['value'].widget.attrs['data-max-length'] = max_length
65 if self.type == 'options':
66 option_set = FieldOptionSet.objects.get(name=options['option_set'])
67 self.fields['value'].widget = forms.Select(choices=option_set.choices(answer))
68 value_options = answer.fieldoption_set.all()
70 self.fields['value'].initial = value_options.get().id
72 value = answer.field_values.get(label)
73 self.fields['value'].initial = value or ''
75 def clean_value(self):
76 if self.type == 'options':
77 value = self.cleaned_data['value']
80 option = FieldOption.objects.get(id=int(value))
81 except (FieldOption.DoesNotExist, ValueError):
82 raise forms.ValidationError(u'Nieprawidłowa wartość.')
83 if option.answer != self.answer and option.answer is not None:
84 raise forms.ValidationError(u'Ta opcja została już wybrana przez kogoś innego.')
86 return self.cleaned_data['value']
89 value = self.cleaned_data['value']
90 if self.type == 'options':
93 if option.answer != self.answer:
95 assert not option.answer
96 for opt in self.answer.fieldoption_set.all():
99 option.answer = self.answer
102 for opt in self.answer.fieldoption_set.all():
106 self.answer.field_values[self.label] = value
110 class MarkForm(forms.ModelForm):
111 answer_id = forms.CharField(widget=forms.HiddenInput)
117 'points': forms.TextInput(attrs={'type': 'number', 'min': 0, 'step': '0.5'})
120 def __init__(self, answer, criterion, *args, **kwargs):
121 super(MarkForm, self).__init__(*args, **kwargs)
122 self.fields['answer_id'].initial = answer.id
123 points_field = self.fields['points']
124 points_field.label = mark_safe(criterion.form_label())
125 points_field.help_text = '(max %s)' % criterion.max_points
126 points_field.min_value = Decimal(0)
127 points_field.max_value = Decimal(criterion.max_points)
128 points_field.widget.attrs['max'] = criterion.max_points