diff --git a/README.md b/README.md index f930a7f..d6c3147 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,3 @@ DB_PASSWORD=... $ python manage.py migrate $ python manage.py runserver ``` - -### Problemy z instalacją - -Mogą pojawić się problemy związane z instalacją `django-crispy-forms==1.12.0`. -Najpierw trzeba zainstalować wszystkie pakiety, potem dokładnie wersję `1.12.0`. -Pomimo błędów ta wersja jest potrzebna do działania diff --git a/app/admin.py b/app/admin.py index 97f2122..11b1dcf 100644 --- a/app/admin.py +++ b/app/admin.py @@ -2,7 +2,6 @@ from django.apps import apps from django.contrib import admin from django.shortcuts import HttpResponse from django.contrib.admin.sites import AlreadyRegistered -from django_summernote.admin import SummernoteModelAdmin from .models import Announcement, Edition, School, Student from django.db import transaction @@ -10,10 +9,6 @@ from io import BytesIO import xlsxwriter -class AnnouncementModelAdmin(SummernoteModelAdmin): - summernote_fields = ['content'] - - class EditionModelAdmin(admin.ModelAdmin): list_display = ('__str__', 'active') ordering = ('-active', '-year') @@ -33,7 +28,8 @@ class EditionModelAdmin(admin.ModelAdmin): if index == 0: continue - Student.objects.filter(identifier=row[0]).update(score_first=row[1], score_second=row[2]) + Student.objects.filter(identifier=row[0]).update( + score_first=row[1], score_second=row[2]) if '_update-disable-submissions' in request.POST and obj.active and obj.submissions: if obj.active is True: @@ -49,7 +45,8 @@ class EditionModelAdmin(admin.ModelAdmin): if '_generate-student-list' in request.POST: year = obj.year students = Student.objects.filter(identifier__startswith=year) - schools_set = {int(student.identifier.split('-')[1]) for student in students} + schools_set = {int(student.identifier.split('-') + [1]) for student in students} output = BytesIO() workbook = xlsxwriter.Workbook(output) @@ -69,15 +66,21 @@ class EditionModelAdmin(admin.ModelAdmin): row = 1 for school_id in schools_set: for student in sorted(Student.objects.filter(identifier__startswith=f'{year}-{school_id}-'), key=lambda x: x.identifier.split('-')[2]): - worksheet.write(row, 0, student.identifier) # Identyfikator - worksheet.write(row, 1, student.score_first) # Wynik - eliminacje - worksheet.write(row, 2, student.score_second) # Wynik - finał + # Identyfikator + worksheet.write(row, 0, student.identifier) + # Wynik - eliminacje + worksheet.write(row, 1, student.score_first) + # Wynik - finał + worksheet.write(row, 2, student.score_second) worksheet.write(row, 3, student.name) # Imię worksheet.write(row, 4, student.surname) # Nazwisko worksheet.write(row, 5, student.grade) # Klasa - worksheet.write(row, 6, student.school_name) # Szkoła - nazwa - worksheet.write(row, 7, student.school_town) # Szkoła - miejscowość - worksheet.write(row, 8, student.school_address) # Szkoła - adres + # Szkoła - nazwa + worksheet.write(row, 6, student.school_name) + # Szkoła - miejscowość + worksheet.write(row, 7, student.school_town) + # Szkoła - adres + worksheet.write(row, 8, student.school_address) row += 1 @@ -93,14 +96,33 @@ class EditionModelAdmin(admin.ModelAdmin): return super().response_change(request, obj) +class StudentYearFilter(admin.SimpleListFilter): + title = 'aktualna edycja' + parameter_name = 'aktualna edycja' + + def lookups(self, request, model_admin): + return ( + ('Yes', 'Jedynie aktualna edycja'), + ) + + def queryset(self, request, queryset): + value = self.value() + year = Edition.current().year + + if value == 'Yes': + return queryset.filter(identifier__startswith=str(year)) + + return queryset + + class StudentModelAdmin(admin.ModelAdmin): list_display = ('identifier', '__str__', 'grade') search_fields = ('identifier', 'name', 'surname', 'grade') - ordering = ('identifier',) + ordering = ('-identifier',) + list_filter = (StudentYearFilter,) admin.site.register(Student, StudentModelAdmin) -admin.site.register(Announcement, AnnouncementModelAdmin) admin.site.register(Edition, EditionModelAdmin) diff --git a/app/migrations/0003_alter_announcement_content.py b/app/migrations/0003_alter_announcement_content.py new file mode 100644 index 0000000..df4f7b0 --- /dev/null +++ b/app/migrations/0003_alter_announcement_content.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.5 on 2022-12-05 02:41 + +from django.db import migrations +import tinymce.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0002_auto_20220420_1823'), + ] + + operations = [ + migrations.AlterField( + model_name='announcement', + name='content', + field=tinymce.models.HTMLField(verbose_name='Treść'), + ), + ] diff --git a/app/migrations/0004_auto_20221205_0348.py b/app/migrations/0004_auto_20221205_0348.py new file mode 100644 index 0000000..91bd3e4 --- /dev/null +++ b/app/migrations/0004_auto_20221205_0348.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.5 on 2022-12-05 02:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0003_alter_announcement_content'), + ] + + operations = [ + migrations.AlterField( + model_name='edition', + name='active', + field=models.BooleanField(default=False, verbose_name='Aktualna edycja'), + ), + migrations.AlterField( + model_name='edition', + name='scores_available', + field=models.BooleanField(default=False, verbose_name='Wyniki finałowe opublikowane'), + ), + migrations.AlterField( + model_name='edition', + name='scores_eliminations', + field=models.BooleanField(default=False, verbose_name='Wyniki z eliminacji opublikowane dla nauczycieli'), + ), + migrations.AlterField( + model_name='edition', + name='submissions', + field=models.BooleanField(default=False, verbose_name='Rejestracja drużyn'), + ), + ] diff --git a/app/models.py b/app/models.py index 16c75a3..2ad4f2e 100644 --- a/app/models.py +++ b/app/models.py @@ -1,26 +1,35 @@ from django.contrib.auth.models import PermissionsMixin from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager from django.db import models, transaction +from tinymce.models import HTMLField class Edition(models.Model): year = models.PositiveIntegerField('Rok', unique=True) roman = models.CharField('Nr. edycji', max_length=25) - active = models.BooleanField('Aktualna', default=False) - submissions = models.BooleanField('Możliwość zgłoszenia drużyny', default=False) + active = models.BooleanField('Aktualna edycja', default=False) + submissions = models.BooleanField( + 'Rejestracja drużyn', default=False) - scores_available = models.BooleanField('Wyniki dostępne dla wszystkich', default=False) - scores_eliminations = models.BooleanField('Wyniki z eliminacji dostępne dla nauczycieli', default=False) + scores_eliminations = models.BooleanField( + 'Wyniki z eliminacji opublikowane dla nauczycieli', default=False) + scores_available = models.BooleanField( + 'Wyniki finałowe opublikowane', default=False) - entry_threshold = models.IntegerField('Próg punkowy - wejście do finału', default=0) - award_threshold = models.IntegerField('Próg punktowy - wyróżnienie', default=0) - laureate_threshold = models.IntegerField('Próg punktowy - tytuł laureata', default=0) + entry_threshold = models.IntegerField( + 'Próg punkowy - wejście do finału', default=0) + award_threshold = models.IntegerField( + 'Próg punktowy - wyróżnienie', default=0) + laureate_threshold = models.IntegerField( + 'Próg punktowy - tytuł laureata', default=0) scores = models.FileField('Wyniki do wczytania', blank=True, upload_to='wyniki', help_text='Uwaga! Wyniki muszą być zawarte w pliku .csv. Kolumny po kolei to odpowiednio: identyfikator ucznia, wynik z eliminacji, wynik z finału.') - first_test = models.FileField('Zadania eliminacyjne', blank=True, upload_to='eliminacje') - second_test = models.FileField('Zadania finałowe', blank=True, upload_to='finaly') + first_test = models.FileField( + 'Zadania eliminacyjne', blank=True, upload_to='eliminacje') + second_test = models.FileField( + 'Zadania finałowe', blank=True, upload_to='finaly') def __str__(self): return f'Edycja {self.roman}' @@ -43,7 +52,8 @@ class Edition(models.Model): class Student(models.Model): name = models.CharField('Imię', max_length=50) surname = models.CharField('Nazwisko', max_length=50) - grade = models.PositiveIntegerField('Klasa', choices=map(lambda x: (x, x), range(1, 9))) + grade = models.PositiveIntegerField( + 'Klasa', choices=map(lambda x: (x, x), range(1, 9))) score_first = models.IntegerField('Wynik z eliminacji', default=0) score_second = models.IntegerField('Wynik z finału', default=0) @@ -65,7 +75,7 @@ class Student(models.Model): class Announcement(models.Model): title = models.CharField('Tytuł', max_length=250) - content = models.TextField('Treść') + content = HTMLField('Treść') created_at = models.DateTimeField(auto_now_add=True) def __str__(self): @@ -115,8 +125,10 @@ class School(AbstractBaseUser, PermissionsMixin): is_staff = models.BooleanField('Staff status', default=False) is_active = models.BooleanField('Active status', default=True) - request_notifications = models.BooleanField('Powiadomienia przy wysłaniu zgłoszenia', default=False) - email_notifications = models.BooleanField('Powiadomienia przy wysłaniu wiadomości email', default=False) + request_notifications = models.BooleanField( + 'Powiadomienia przy wysłaniu zgłoszenia', default=False) + email_notifications = models.BooleanField( + 'Powiadomienia przy wysłaniu wiadomości email', default=False) objects = UserManager() diff --git a/app/templates/admin/edition_buttons.html b/app/templates/admin/edition_buttons.html index 9bcd670..923673e 100644 --- a/app/templates/admin/edition_buttons.html +++ b/app/templates/admin/edition_buttons.html @@ -3,7 +3,7 @@