from django import forms from dal import autocomplete from django.contrib.auth.forms import PasswordResetForm from django.core.exceptions import ObjectDoesNotExist from django.contrib.auth.models import User from seminar.models import Skola, Resitel, Osoba from datetime import date import logging # pro přidání políčka do formuláře je potřeba # - mít v modelu tu položku, kterou chci upravovat # - přidat do views (prihlaskaView, resitelEditView) # - přidat do forms # - includovat do html class DateInput(forms.DateInput): # aby se datum dalo vybírat z kalendáře input_type = 'date' class TelInput(forms.TextInput): # tohle je možná k niřemu, ale alepsoň to mění input type a nic to nekazí input_type = 'tel' input_pattern="^[+]?[()/0-9. -]{9,}$" class UdajeForm(forms.Form): username = None err_logger = logging.getLogger('seminar.prihlaska.problem') jmeno = forms.CharField(label='Jméno', max_length=256, required=True) prezdivka_resitele = forms.CharField(label='Přezdívka (veřejná)', max_length=256, required=False) prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) osloveni = forms.ChoiceField(label='Oslovení', choices=Osoba.OSLOVENI_CHOICES, required=False) email = forms.EmailField(label='E-mail', max_length=256, required=True) telefon = forms.CharField(widget=TelInput(), label='Telefon', max_length=256, required=False) datum_narozeni = forms.DateField(widget=DateInput(), label='Datum narození', required=False) ulice = forms.CharField(label='Ulice a číslo popisné', max_length=256, required=False) mesto = forms.CharField(label='Město', max_length=256, required=False) psc = forms.CharField(label='PSČ', max_length=32, required=False) stat = forms.ChoiceField(label='Stát', choices=(('CZ', 'Česká republika'), ('SK', 'Slovenská republika'), ('other', 'Jiné')), required=False) stat_text = forms.CharField(label='Stát', max_length=256, required=False) skola = forms.ModelChoiceField( label="Škola", queryset=Skola.objects.all(), widget=autocomplete.ModelSelect2( url='autocomplete_skola', attrs={ 'data-placeholder--id': '-1', 'data-placeholder--text': '---', 'data-allow-clear': 'true' } ), required=False, ) skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) rok_maturity = forms.IntegerField( label='Rok maturity', min_value=date.today().year, max_value=date.today().year+13, required=True, ) zasilat = forms.ChoiceField(label='Kam zasílat (odměny, pozvánky, případně čísla nebo propagační materiály)', choices=[it for it in Resitel.ZASILAT_CHOICES if it[0] != Resitel.ZASILAT_NIKAM], required=True, initial=Resitel.ZASILAT_DOMU) zasilat_cislo_papirove = forms.BooleanField(label='Chci dostávat čísla poštou (zasílání není zpoplatněno)', required=False, initial=False) zasilat_cislo_emailem = forms.BooleanField(label='Chci dostávat e-mailem upozornění na vydání nového čísla', required=False, initial=True) spam = forms.BooleanField(label='Souhlasím se zasíláním propagačních materiálů od MFF UK', required=False) def clean_prezdivka_resitele(self): prezdivka_resitele = self.cleaned_data.get('prezdivka_resitele') if prezdivka_resitele == '': return prezdivka_resitele if Resitel.objects.filter(prezdivka_resitele=prezdivka_resitele).exclude(osoba__user__username=self.username).count() > 0: raise forms.ValidationError('Přezdívka je již použita') return prezdivka_resitele def clean_email(self): email = self.cleaned_data.get('email') try: osoba = Osoba.objects.exclude(user__username=self.username).get(email=email) msg = "Email {} exists".format(email) if osoba.user is not None: self.err_logger.info(msg) raise forms.ValidationError('E-mail je již použit') else: msg += ', but currently has no User, so allowing registration.' self.err_logger.info(msg) except ObjectDoesNotExist: pass return email def clean_zasilat(self): zasilat = self.cleaned_data.get('zasilat') ulice = self.cleaned_data.get('ulice') if zasilat == Resitel.ZASILAT_DOMU and ulice == "": raise forms.ValidationError('Nevyplněná adresa bydliště, nelze zasílat domů.') return zasilat def clean(self): super().clean() data = self.cleaned_data if data.get('stat') != 'other' and data.get('stat_text') != '': self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem')) if data.get('skola') and (data.get('skola_nazev') or data.get('skola_adresa')): self.add_error('skola',forms.ValidationError('Pokud je škola v seznamu, nevypisujte ji ručně, pokud není, zrušte výběr ze seznamu (křížek vpravo)')) if not data.get('skola'): if data.get('skola_nazev')=='' and data.get('skola_adresa')=='': self.add_error('skola',forms.ValidationError('Je nutné vyplnit školu')) elif data.get('skola_nazev')=='': 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 PrihlaskaForm(PasswordResetForm, UdajeForm): username = forms.CharField( label='Přihlašovací jméno', max_length=256, required=True, help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři', ) jak_se_dozvedeli = forms.CharField(widget=forms.Textarea({"rows": 3, "cols": 20}), label='Jak ses o M&M dozvěděl(a)? (Nechceš-li odpovídat, napiš „nechci uvést“.)', required=True) gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True) def clean_username(self): username = self.cleaned_data.get('username') try: User.objects.get(username=username) msg = "Username {} exists".format(username) self.err_logger.info(msg) raise forms.ValidationError('Přihlašovací jméno je již použito') except ObjectDoesNotExist: pass return username class ProfileEditForm(UdajeForm): err_logger = logging.getLogger('seminar.edit.problem') username = forms.CharField( label='Přihlašovací jméno', max_length=256, required=False, disabled=True, ) class PoMaturiteProfileEditForm(ProfileEditForm): rok_maturity = forms.IntegerField( label='Rok maturity', required=True)