Compare commits

...

3 Commits

Author SHA1 Message Date
Karel Balej 1dfeeaa9d1 odevzdavatko: odesílání upozornění na změnu zpětné vazby 1 year ago
Karel Balej c8b2d07605 odevzdavatko: zjednodušení editace hodnocení řešení 1 year ago
Karel Balej 288c8ad459 odevzdavatko: zjednodušení DetailReseniView 1 year ago
  1. 22
      odevzdavatko/forms.py
  2. 1
      odevzdavatko/templates/odevzdavatko/detail.html
  3. 66
      odevzdavatko/views.py
  4. 1
      personalni/forms.py
  5. 9
      personalni/templates/personalni/udaje/edit.html
  6. 1
      personalni/views.py
  7. 18
      seminar/migrations/0110_resitel_upozorneni.py
  8. 2
      seminar/models/personalni.py

22
odevzdavatko/forms.py

@ -1,7 +1,6 @@
from django import forms
from dal import autocomplete
from django.forms import formset_factory
from django.forms.models import inlineformset_factory
from django.forms.models import modelformset_factory, inlineformset_factory
from django.utils import timezone
from seminar.models import Resitel
@ -85,19 +84,14 @@ ReseniSPrilohamiFormSet = inlineformset_factory(m.Reseni,m.PrilohaReseni,
)
class JednoHodnoceniForm(forms.ModelForm):
class Meta:
model = m.Hodnoceni
fields = ('problem', 'body', 'deadline_body', 'feedback',)
widgets = {
'problem': autocomplete.ModelSelect2(
url='autocomplete_problem',
),
HodnoceniFormSet = modelformset_factory(
m.Hodnoceni,
fields=('id', 'problem', 'body', 'deadline_body', 'feedback',),
extra=0,
widgets={
'problem': autocomplete.ModelSelect2(url='autocomplete_problem',),
'feedback': forms.Textarea(attrs={'rows': 1, 'cols': 30, 'class': 'feedback'}),
}
OhodnoceniReseniFormSet = formset_factory(JednoHodnoceniForm,
extra = 0,
},
)
class PoznamkaReseniForm(forms.ModelForm):

1
odevzdavatko/templates/odevzdavatko/detail.html

@ -112,6 +112,7 @@ $(document).ready(function(){
<td class="has_smazat_hodnoceni"><a href="#" class="smazat_hodnoceni" id="id_{{subform.prefix}}-jsremove" title="Smazat hodnocení"><img src="{% static "odevzdavatko/cross.png" %}" alt="Smazat"></a></td>
</tr>
</tbody>
{{ subform.id }}
{% endfor %}
</table>

66
odevzdavatko/views.py

@ -1,7 +1,7 @@
from django.core.exceptions import PermissionDenied
from django.views.generic import ListView, DetailView, FormView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.mail import send_mail
from django.core.mail import send_mail, EmailMessage
from django.utils import timezone
from django.views.generic import ListView, DetailView, FormView, CreateView
from django.views.generic.list import MultipleObjectTemplateResponseMixin,MultipleObjectMixin
@ -219,58 +219,46 @@ class DetailReseniView(DetailView):
model = m.Reseni
template_name = 'odevzdavatko/detail.html'
def aktualni_hodnoceni(self):
self.reseni = get_object_or_404(m.Reseni, id=self.kwargs['pk'])
result = [] # Slovníky s klíči problem, body, deadline_body -- initial data pro f.OhodnoceniReseniFormSet
for hodn in m.Hodnoceni.objects.filter(reseni=self.reseni):
result.append({
"problem": hodn.problem,
"body": hodn.body,
"deadline_body": hodn.deadline_body,
"feedback": hodn.feedback,
})
return result
def get_context_data(self, **kw):
reseni = get_object_or_404(m.Reseni, id=self.kwargs['pk'])
ctx = super().get_context_data(**kw)
ctx['form'] = f.OhodnoceniReseniFormSet(
initial = self.aktualni_hodnoceni()
)
ctx['poznamka_form'] = f.PoznamkaReseniForm(instance=self.reseni)
ctx['form'] = f.HodnoceniFormSet(queryset=m.Hodnoceni.objects.filter(reseni=reseni))
ctx['poznamka_form'] = f.PoznamkaReseniForm(instance=reseni)
return ctx
def hodnoceniReseniView(request, pk, *args, **kwargs):
reseni = get_object_or_404(m.Reseni, pk=pk)
template_name = 'odevzdavatko/detail.html'
form_class = f.OhodnoceniReseniFormSet
form_class = f.HodnoceniFormSet
success_url = reverse('odevzdavatko_detail_reseni', kwargs={'pk': pk})
# FIXME: Použit initial i tady a nebastlit hodnocení tak nízkoúrovňově
# Also: https://docs.djangoproject.com/en/2.2/topics/forms/modelforms/#django.forms.ModelForm
formset = f.OhodnoceniReseniFormSet(request.POST)
hodnoceni_formset = f.HodnoceniFormSet(request.POST, queryset=m.Hodnoceni.objects.filter(reseni=reseni))
poznamka_form = f.PoznamkaReseniForm(request.POST, instance=reseni)
# TODO: Napsat validaci formuláře a formsetu
if not (formset.is_valid() and poznamka_form.is_valid()):
raise ValueError(formset.errors, poznamka_form.errors)
if not (hodnoceni_formset.is_valid() and poznamka_form.is_valid()):
raise ValueError(hodnoceni_formset.errors, poznamka_form.errors)
with transaction.atomic():
# Poznámka je jednoduchá na zpracování:
poznamka_form.save()
# Smažeme všechna dosavadní hodnocení tohoto řešení
qs = m.Hodnoceni.objects.filter(reseni=reseni)
logger.info(f"Will delete {qs.count()} objects: {qs}")
qs.delete()
# Vyrobíme nová podle formsetu
for form in formset:
hodnoceni = m.Hodnoceni(
reseni=reseni,
**form.cleaned_data,
)
logger.info(f"Creating Hodnoceni: {hodnoceni}")
hodnoceni.save()
if poznamka_form.has_changed(): poznamka_form.save()
if hodnoceni_formset.has_changed(): hodnoceni_formset.save()
zmeny = []
for hodnoceni_form in hodnoceni_formset:
if 'feedback' in hodnoceni_form.changed_data:
zmeny.append(hodnoceni_form.instance)
if zmeny:
adresati = reseni.resitele.filter(upozorneni=True).values_list('osoba__email', flat=True)
if adresati:
email = EmailMessage(
subject='Změna zpětné vazby k Tvému řešení',
body='\n\n'.join([f'{hodnoceni.problem}\n{hodnoceni.feedback}' for hodnoceni in zmeny]) + f'\n\nNechceš-li toto upozornění dostávat, můžeš jej vypnout v nastavení svého účtu.\n\nTvoji organizátoři M&M',
from_email='odevzdavatko@mam.mff.cuni.cz',
to=adresati,
reply_to=[request.user.email] or None,
)
email.send()
return redirect(success_url)

1
personalni/forms.py

@ -177,6 +177,7 @@ class ProfileEditForm(forms.Form):
zasilat_cislo_emailem = forms.BooleanField(label='Chci dostávat email s upozorněním na vydání nového čísla', required=False)
spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False)
upozorneni = forms.BooleanField(label='Chci dostat email, když opravovatel přidá zpětnou vazbu k mému řešení', required=False)
# def clean_username(self):
# err_logger = logging.getLogger('seminar.prihlaska.problem')
# username = self.cleaned_data.get('username')

9
personalni/templates/personalni/udaje/edit.html

@ -97,6 +97,15 @@
{% include "personalni/udaje/prihlaska_field.html" with field=form.spam %}
</table>
<hr>
<h4>
Zasílání upozornění na zpětnou vazbu k řešení
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.upozorneni %}
</table>
<hr>
<input type="submit" value="Změnit">

1
personalni/views.py

@ -164,6 +164,7 @@ def resitelEditView(request):
resitel_edit.rok_maturity = fcd['rok_maturity']
resitel_edit.zasilat = fcd['zasilat']
resitel_edit.zasilat_cislo_emailem = fcd['zasilat_cislo_emailem']
resitel_edit.upozorneni = fcd['upozorneni']
if fcd.get('skola'):
resitel_edit.skola = fcd['skola']
else:

18
seminar/migrations/0110_resitel_upozorneni.py

@ -0,0 +1,18 @@
# Generated by Django 3.2.16 on 2022-12-19 22:36
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('seminar', '0109_hodnoceni_feedback'),
]
operations = [
migrations.AddField(
model_name='resitel',
name='upozorneni',
field=models.BooleanField(default=True),
),
]

2
seminar/models/personalni.py

@ -237,6 +237,8 @@ class Resitel(SeminarModelBase):
poznamka = models.TextField('neveřejná poznámka', blank=True,
help_text='Neveřejná poznámka k řešiteli (plain text)')
upozorneni = models.BooleanField(default=True)
def export_row(self):
"Slovnik pro pouziti v AESOP exportu"

Loading…
Cancel
Save