foerderbarometer/input/forms.py

382 lines
9.7 KiB
Python
Raw Permalink Normal View History

2025-10-15 12:46:28 +00:00
from django import forms
from django.conf import settings
2020-09-29 10:16:10 +00:00
from django.contrib.admin.widgets import AdminDateWidget
from django.forms import ModelForm
2025-08-20 12:28:46 +00:00
from django.forms.renderers import DjangoTemplates
from django.utils.html import format_html
from django.utils.safestring import mark_safe
2025-11-10 16:54:03 +00:00
from django.utils.translation import gettext_lazy as trans
2025-10-15 12:46:28 +00:00
from .models import (
Project,
ProjectCategory,
WikimediaProject,
IFG,
Library,
ELiterature,
Software,
Travel,
Email,
Literature,
List,
BusinessCard,
)
2020-09-29 07:54:31 +00:00
2020-11-17 15:11:10 +00:00
2025-08-20 12:28:46 +00:00
class TableFormRenderer(DjangoTemplates):
"""
Set in settings as the default form renderer.
"""
form_template_name = 'django/forms/table.html'
2020-10-21 07:54:12 +00:00
class RadioField(forms.ChoiceField):
widget = forms.RadioSelect
2020-10-21 07:54:12 +00:00
class BaseApplicationForm(ModelForm):
"""
Base form for all external applications.
"""
required_css_class = 'required'
check = forms.BooleanField(
required=True,
label=format_html(
"""Ich stimme den <a href="{}" target="_blank" rel="noopener">Datenschutzbestimmungen</a> und der<br>
<a href="{}" target="_blank" rel="noopener">Richtlinie zur Förderung der Communitys</a> zu.""",
settings.DATAPROTECTION,
settings.FOERDERRICHTLINIEN
),
)
PROJECT_COST_GT_1000_MESSAGE = format_html(
"""Bitte beachte, dass für Projektkosten über 1.000 € ein öffentlicher Projektplan erforderlich
ist (siehe <a href="{0}" target="blank_">Wikipedia:Förderung/Projektplanung)</a>.""",
'https://de.wikipedia.org/wiki/Wikipedia:F%C3%B6rderung/Projektplanung'
)
class BaseProjectForm(ModelForm):
categories = {
'categories': ProjectCategory,
'wikimedia_projects': WikimediaProject,
}
class Media:
js = ('dropdown/js/otrs_link.js', 'js/project-categories.js')
def clean(self):
cleaned_data = ModelForm.clean(self)
if self.errors:
return cleaned_data
for field, model in self.categories.items():
field_other = f'{field}_other'
values = cleaned_data[field]
if model.other in values:
if not cleaned_data[field_other]:
2025-10-16 15:00:40 +00:00
self.add_error(field_other, f'Bitte gib einen Wert an oder deselektiere "{model.OTHER}".')
else:
cleaned_data[field_other] = ''
return cleaned_data
class ProjectForm(BaseProjectForm, BaseApplicationForm):
OPTIONAL_FIELDS = {
'categories_other',
'wikimedia_projects_other',
'page',
'group',
'location',
'insurance',
'notes',
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in set(self.fields) - self.OPTIONAL_FIELDS:
self.fields[field].required = True
class Meta:
model = Project
fields = [
'realname',
'email',
'name',
'description',
'categories',
'categories_other',
'wikimedia_projects',
'wikimedia_projects_other',
'start',
'end',
'participants_estimated',
'page',
'group',
'location',
'cost',
'insurance',
'notes',
]
labels = {
'cost': 'Kosten in Euro',
'insurance': 'Haftpflicht- und Unfallversicherung gewünscht',
'participants_estimated': 'Voraussichtliche Zahl der Teilnehmenden',
}
widgets = {
'start': AdminDateWidget,
'end': AdminDateWidget,
}
class Media:
css = {
'all': ('css/dateFieldNoNowShortcutInTravels.css',)
}
def clean_cost(self):
cost = self.cleaned_data['cost']
if cost > 1000:
raise forms.ValidationError(PROJECT_COST_GT_1000_MESSAGE, code='cost-gt-1000')
return cost
2025-10-15 12:46:28 +00:00
HOTEL_CHOICES = {
'TRUE': mark_safe('Hotelzimmer benötigt'),
'FALSE': mark_safe('Kein Hotelzimmer benötigt'),
}
class TravelForm(BaseApplicationForm):
2020-11-03 11:56:40 +00:00
# TODO: add some javascript to show/hide other-field
2025-08-19 12:10:15 +00:00
hotel = RadioField(label='Hotelzimmer benötigt', choices=HOTEL_CHOICES)
2025-10-15 12:46:28 +00:00
# this is the code, to change required to false if needed
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['project_name'].required = True
self.fields['transport'].required = True
self.fields['travelcost'].required = True
2025-11-07 14:28:45 +00:00
self.fields['travelcost'].initial = None
self.fields['checkin'].required = True
self.fields['checkout'].required = True
self.fields['hotel'].required = True
2020-10-26 10:38:56 +00:00
class Meta:
model = Travel
fields = [
'realname',
'email',
'project_name',
'transport',
'travelcost',
'checkin',
'checkout',
'hotel',
'notes',
]
labels = {
'checkin': 'Datum der Anreise',
'checkout': 'Datum der Abreise',
}
2025-10-15 12:46:28 +00:00
widgets = {
'checkin': AdminDateWidget,
'checkout': AdminDateWidget,
}
2020-10-21 07:54:12 +00:00
class Media:
js = ('dropdown/js/otrs_link.js',)
css = {
2025-10-15 12:46:28 +00:00
'all': ('css/dateFieldNoNowShortcutInTravels.css',)
}
class LibraryForm(BaseApplicationForm):
2020-10-19 11:29:36 +00:00
2020-10-01 08:51:19 +00:00
class Meta:
model = Library
fields = [
'realname',
'email',
'cost',
'library',
'duration',
'notes',
]
labels = {
'cost': 'Kosten in Euro',
}
2020-10-01 08:51:19 +00:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['library'].label = self._meta.model.LIBRARY_LABEL
self.fields['library'].help_text = self._meta.model.LIBRARY_HELP_TEXT
self.fields['duration'].help_text = self._meta.model.DURATION_HELP_TEXT
class ELiteratureForm(LibraryForm):
class Meta(LibraryForm.Meta):
model = ELiterature
class SoftwareForm(LibraryForm):
class Meta(LibraryForm.Meta):
model = Software
class IFGForm(BaseApplicationForm):
2020-11-18 17:02:23 +00:00
2020-10-01 08:51:19 +00:00
class Meta:
2020-10-01 10:08:02 +00:00
model = IFG
fields = [
'realname',
'email',
'cost',
'url',
'notes',
]
2020-10-21 07:54:12 +00:00
2020-10-27 10:00:58 +00:00
class TermsForm(BaseApplicationForm):
terms_accepted_label = 'Ich stimme den <a href="{}">Nutzungsbedingungen</a> zu.'
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN
2025-06-16 09:43:08 +00:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['terms_accepted'].required = True
self.fields['terms_accepted'].label = format_html(self.terms_accepted_label, self.terms_accepted_url)
2020-11-18 17:02:23 +00:00
class LiteratureForm(TermsForm):
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN_LITERATURSTIPENDIUM
2025-06-16 09:43:08 +00:00
class Meta:
model = Literature
fields = [
'realname',
'email',
'cost',
'info',
'source',
'notes',
'selfbuy',
'selfbuy_data',
'selfbuy_give_data',
'terms_accepted',
]
2025-10-15 12:46:28 +00:00
class Media:
2023-02-27 17:09:29 +00:00
js = ('dropdown/js/literature.js',)
2025-11-10 16:54:03 +00:00
def clean(self):
cleaned_data = TermsForm.clean(self)
if self.errors:
return cleaned_data
if cleaned_data['selfbuy'] == 'TRUE':
cleaned_data['selfbuy_data'] = ''
cleaned_data['selfbuy_give_data'] = False
2025-11-10 17:06:21 +00:00
return cleaned_data
for field in 'selfbuy_data', 'selfbuy_give_data':
2025-11-11 08:47:51 +00:00
if not cleaned_data.get(field):
2025-11-10 17:06:21 +00:00
self.add_error(field, trans('This field is required.'))
2025-11-10 16:54:03 +00:00
return cleaned_data
2025-10-15 12:46:28 +00:00
ADULT_CHOICES = {
'TRUE': mark_safe('Ich bin volljährig.'),
'FALSE': mark_safe('Ich bin noch nicht volljährig.'),
}
2025-06-16 09:43:08 +00:00
class EmailForm(TermsForm):
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN_EMAIL_SERVICE
2025-08-19 12:10:15 +00:00
2023-02-27 17:09:29 +00:00
# this is the code, to change required to false if needed
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['adult'].required = True
2023-02-27 17:09:29 +00:00
self.fields['other'].required = True
2023-02-27 17:09:29 +00:00
adult = RadioField(label='Volljährigkeit', choices=ADULT_CHOICES)
2020-10-27 10:00:58 +00:00
# TODO: add some javascript to show/hide other-field
class Meta:
model = Email
fields = [
'realname',
'email',
'domain',
'address',
'other',
'adult',
'terms_accepted',
]
2025-10-15 12:46:28 +00:00
class Media:
2023-02-27 17:09:29 +00:00
js = ('dropdown/js/mail.js',)
class BusinessCardForm(TermsForm):
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN_VISITENKARTEN
2025-10-15 12:46:28 +00:00
2025-06-16 09:43:08 +00:00
# this is the code, to change required to false if needed
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['url_of_pic'].required = True
2023-02-27 17:09:29 +00:00
self.fields['send_data_to_print'].required = True
2025-06-16 09:43:08 +00:00
class Meta:
model = BusinessCard
fields = [
'realname',
'email',
'project',
'data',
'variant',
'url_of_pic',
'send_data_to_print',
'sent_to',
'terms_accepted',
]
2025-10-15 12:46:28 +00:00
2025-06-16 09:43:08 +00:00
class Media:
2023-02-27 17:09:29 +00:00
js = ('dropdown/js/businessCard.js',)
class ListForm(TermsForm):
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN_MAILINGLISTEN
2025-10-15 12:46:28 +00:00
class Meta:
model = List
fields = [
'realname',
'email',
'domain',
'address',
'terms_accepted',
]
2025-10-14 09:16:13 +00:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['address'].initial = ''