From a674d837ae6652ad255de5034e3ca3176e4cd87d Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 5 Feb 2020 23:30:41 +0100 Subject: [PATCH 1/3] forms | Pridan prototyp formulare na odevzdavani reseni. --- seminar/forms.py | 47 ++++++++++++++++++- .../templates/seminar/org/vloz_reseni.html | 17 +++++++ seminar/urls.py | 5 ++ seminar/views.py | 26 ++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 seminar/templates/seminar/org/vloz_reseni.html diff --git a/seminar/forms.py b/seminar/forms.py index b28beeb9..9ce38e68 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -3,7 +3,8 @@ from dal import autocomplete from django.core.exceptions import ObjectDoesNotExist from django.contrib.auth.models import User -from .models import Skola, Resitel, Osoba +from .models import Skola, Resitel, Osoba, Problem +import seminar.models as m from datetime import date import logging @@ -210,3 +211,47 @@ class EditForm(forms.Form): # self.add_error('skola_nazev',forms.ValidationError('Je nutné vyplnit název školy')) # elif data.get('skola_adresa')=='': # self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) + +class VlozReseniForm(forms.Form): + #FIXME jen podproblémy daného problému + problem = forms.ModelChoiceField(label='Problém',queryset=m.Problem.objects.all()) + # to_field_name + #problem = models.ManyToManyField(Problem, verbose_name='problém', help_text='Problém', + # through='Hodnoceni') + + # FIXME pridat vice resitelu + resitel = forms.ModelChoiceField(label="Řešitel", + queryset=Resitel.objects.all(), + widget=autocomplete.ModelSelect2( + url='autocomplete_resitel', + attrs = {'data-placeholder--id': '-1', + 'data-placeholder--text' : '---', + 'data-allow-clear': 'true'}) + ) + + + #resitele = models.ManyToManyField(Resitel, verbose_name='autoři řešení', + # help_text='Seznam autorů řešení', through='Reseni_Resitele') + + cas_doruceni = forms.DateField(label="Čas doručení") + + #cas_doruceni = models.DateTimeField('čas_doručení', default=timezone.now, blank=True) + + forma = forms.ChoiceField(label="Forma řešení",choices = m.Reseni.FORMA_CHOICES) + #forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, + # default=FORMA_EMAIL) + + poznamka = forms.CharField(label='Neveřejná poznámka') + #poznamka = models.TextField('neveřejná poznámka', blank=True, + # help_text='Neveřejná poznámka k řešení (plain text)') + + #TODO body do cisla + #TODO prilohy + + def __init__(self, *args, **kwargs): + super(VlozReseniForm, self).__init__(*args, **kwargs) + #self.fields['favorite_color'] = forms.ChoiceField(choices=[(color.id, color.name) for color in Resitel.objects.all()]) + + + + diff --git a/seminar/templates/seminar/org/vloz_reseni.html b/seminar/templates/seminar/org/vloz_reseni.html new file mode 100644 index 00000000..4339e0e3 --- /dev/null +++ b/seminar/templates/seminar/org/vloz_reseni.html @@ -0,0 +1,17 @@ +{% extends "seminar/zadani/base.html" %} +{% load staticfiles %} +{% block script %} + + {{form.media}} + +{% endblock %} + +{% block content %} +

+ {% block nadpis1a %}{% block nadpis1b %} + Přihláška do semináře + {% endblock %}{% endblock %} +

+{{form.as_p}} + +{% endblock %} diff --git a/seminar/urls.py b/seminar/urls.py index 57e447f3..84775838 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -108,12 +108,17 @@ urlpatterns = [ path('auth/logout/', views.LogoutView.as_view(), name='logout'), path('auth/resitel/', views.ResitelView.as_view(), name='seminar_resitel'), path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'), + path('autocomplete/resitel/',views.ResitelAutocomplete.as_view(), name='autocomplete_resitel'), path('auth/reset_password/', views.PasswordResetView.as_view(), name='reset_password'), path('auth/change_password/', views.PasswordChangeView.as_view(), name='change_password'), path('auth/reset_password_done/', views.PasswordResetDoneView.as_view(), name='reset_password_done'), path('auth/reset_password_confirm///', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'), path('auth/reset_password_complete/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'), path('auth/resitel_edit', views.resitelEditView, name='seminar_resitel_edit'), + + + path('temp/add_solution', views.AddSolutionView.as_view()), + path('', views.TitulniStranaView.as_view(), name='titulni_strana'), # Ceka na autocomplete v3 diff --git a/seminar/views.py b/seminar/views.py index b4c710a5..c43a0043 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -9,6 +9,7 @@ from django.utils.translation import ugettext as _ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q, Sum, Count from django.views.decorators.csrf import ensure_csrf_cookie +from django.views.generic.edit import FormView from django.contrib.auth import authenticate, login, get_user_model, logout from django.contrib.auth import views as auth_views from django.contrib.auth.models import User @@ -22,6 +23,7 @@ from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Orga from . import utils from .unicodecsv import UnicodeWriter from .forms import PrihlaskaForm, LoginForm, EditForm +import seminar.forms as f from datetime import timedelta, date, datetime from django.utils import timezone @@ -1123,6 +1125,11 @@ class ResitelView(LoginRequiredMixin,generic.DetailView): return Resitel.objects.get(osoba__user=self.request.user) ## Formulare +class AddSolutionView(LoginRequiredMixin, FormView): + template_name = 'seminar/org/vloz_reseni.html' + form_class = f.VlozReseniForm + success_url = '/' + def resetPasswordView(request): pass @@ -1297,6 +1304,25 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView): return qs +class LoginRequiredAjaxMixin(object): + def dispatch(self, request, *args, **kwargs): + #if request.is_ajax() and not request.user.is_authenticated: # Pokud to otevřu jako stránku, tak se omezení neuplatní, takže to asi nechceme + if not request.user.is_authenticated: + return JsonResponse(data={'results': [], 'pagination': {}}, status=401) + return super(LoginRequiredAjaxMixin, self).dispatch(request, *args, **kwargs) + +class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView): + def get_queryset(self): + qs = Resitel.objects.all() + if self.q: + qs = qs.filter( + Q(osoba__jmeno__startswith=self.q)| + Q(osoba__prijmeni__startswith=self.q)| + Q(osoba__prezdivka__startswith=self.q) + ) + return qs + + # Ceka na autocomplete v3 # class OrganizatorAutocomplete(autocomplete.Select2QuerySetView): # def get_queryset(self): From e63253f848e00f29a62ecef9015db7c773a97a8f Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 5 Feb 2020 23:59:21 +0100 Subject: [PATCH 2/3] Forms | Prace na vkladani reseni. --- seminar/templates/seminar/org/vloz_reseni.html | 6 +++++- seminar/urls.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/seminar/templates/seminar/org/vloz_reseni.html b/seminar/templates/seminar/org/vloz_reseni.html index 4339e0e3..bfe4f6f6 100644 --- a/seminar/templates/seminar/org/vloz_reseni.html +++ b/seminar/templates/seminar/org/vloz_reseni.html @@ -9,9 +9,13 @@ {% block content %}

{% block nadpis1a %}{% block nadpis1b %} - Přihláška do semináře + Vložit řešení {% endblock %}{% endblock %}

+
+ {% csrf_token %} {{form.as_p}} + +
{% endblock %} diff --git a/seminar/urls.py b/seminar/urls.py index 84775838..bc1c89a8 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -117,7 +117,7 @@ urlpatterns = [ path('auth/resitel_edit', views.resitelEditView, name='seminar_resitel_edit'), - path('temp/add_solution', views.AddSolutionView.as_view()), + path('temp/add_solution', views.AddSolutionView.as_view(),name='seminar_vloz_reseni'), path('', views.TitulniStranaView.as_view(), name='titulni_strana'), From 0e1eca9fcb3e917b548043b3258c731f5b8087ef Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Sat, 8 Feb 2020 03:45:53 +0100 Subject: [PATCH 3/3] =?UTF-8?q?TreeNode.print=5Ftree()=20vypisuje=20smyslu?= =?UTF-8?q?pln=C3=BD=20n=C3=A1zev=20dan=C3=A9ho=20node.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/seminar/models.py b/seminar/models.py index 95441384..768b430a 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1262,8 +1262,10 @@ class TreeNode(PolymorphicModel): verbose_name = "Srolovatelné", help_text = "Bude na stránce témátka možnost tuto položku skrýt") + # Slouží k debugování pro rychlé získání představy o podobě podstromu pod tímto TreeNode. def print_tree(self,indent=0): - print("{}TreeNode({})".format(" "*indent,self.id)) + # FIXME: Tady se spoléháme na to, že nedeklarovaný primární klíč se jmenuje by default 'id', což není úplně správně + print("{}{} (id: {})".format(" "*indent,self, self.id)) if self.first_child: self.first_child.print_tree(indent=indent+2) if self.succ: