diff --git a/input/views.py b/input/views.py
index 46c92c7..6c92635 100755
--- a/input/views.py
+++ b/input/views.py
@@ -8,6 +8,7 @@ from django.core.mail import BadHeaderError, EmailMultiAlternatives
from django.template.loader import get_template
from django.conf import settings
from django.contrib.auth.decorators import login_required
+from django.views.generic.edit import FormView
from .forms import (
ExternForm,
@@ -29,6 +30,30 @@ LIBRARY_FORMS = {
TYPE_SOFT: SoftwareForm,
}
+HELP_TEXTS = {
+ "IFG": {
+ "notes": (
+ "Bitte gib an, wie die gewonnenen Informationen den
"
+ "Wikimedia-Projekten zugute kommen sollen."
+ )
+ },
+ "MAIL": {
+ "domain": (
+ "Mit welcher Domain, bzw. für welches Wikimedia-Projekt,
"
+ "möchtest du eine Mailadresse beantragen?"
+ )
+ },
+ "LIT": {
+ "notes": "Bitte gib an, wofür du die Literatur verwenden möchtest."
+ },
+ "LIST": {
+ "domain": (
+ "Mit welcher Domain, bzw. für welches Wikimedia-Projekt,
"
+ "möchtest du eine Mailingliste beantragen?"
+ )
+ },
+}
+
def auth_deny(choice, pk, auth):
if choice not in MODELS:
@@ -66,146 +91,166 @@ def deny(request, choice, pk):
def done(request):
- return HttpResponse("Deine Anfrage wurde gesendet. Du erhältst in Kürze eine E-Mail-Benachrichtigung mit deinen Angaben. Für alle Fragen kontaktiere bitte das Team Communitys und Engagement unter community@wikimedia.de.")
+ return HttpResponse(
+ "Deine Anfrage wurde gesendet. Du erhältst in Kürze eine E-Mail-Benachrichtigung mit deinen Angaben. Für alle Fragen kontaktiere bitte das Team Communitys und Engagement unter community@wikimedia.de.")
def index(request):
return render(request, 'input/index.html')
-class ExternView(CookieWizardView):
- '''This View is for Volunteers'''
+class BaseApplicationView(FormView):
+ """
+ Base view for all application types.
- template_name = "input/extern.html"
- form_list = [ExternForm, LibraryForm]
-
- def get_form(self, step=None, data=None, files=None):
- '''this function determines which part of the multipart form is
- displayed next'''
-
- if step is None:
- step = self.steps.current
- print ("get_form() step " + step)
-
- if step == '1':
- prev_data = self.get_cleaned_data_for_step('0')
- choice = prev_data.get('choice')
- print(f'choice detection in ExternView: {TYPE_CHOICES[choice]}')
- if choice == 'IFG':
- form = IFGForm(data)
- form.fields['notes'].help_text = mark_safe("Bitte gib an, wie die gewonnenen Informationen den
Wikimedia-Projekten zugute kommen sollen.")
- elif choice in LIBRARY_FORMS:
- form = LIBRARY_FORMS[choice](data)
- elif choice == 'MAIL':
- form = EmailForm(data)
- form.fields['domain'].help_text = mark_safe("Mit welcher Domain, bzw. für welches Wikimedia-Projekt,
möchtest du eine Mailadresse beantragen?")
- elif choice == 'LIT':
- form = LiteratureForm(data)
- form.fields['notes'].help_text = "Bitte gib an, wofür du die Literatur verwenden möchtest."
- elif choice == 'VIS':
- form = BusinessCardForm(data)
- elif choice == 'LIST':
- form = ListForm(data)
- form.fields['domain'].help_text = mark_safe("Mit welcher Domain, bzw. für welches Wikimedia-Projekt,
möchtest du eine Mailingliste beantragen?")
- elif choice == 'TRAV':
- form = TravelForm(data)
- else: # pragma: no cover
- raise RuntimeError(f'ERROR! UNKNOWN FORMTYPE {choice} in ExternView')
- self.choice = choice
- else:
- form = super().get_form(step, data, files)
- return form
+ - Each application type (travel, literature, email, etc.) gets its own subclass.
+ - Renders the generic form template.
+ - Handles saving the submitted form to the database.
+ - Adds extra fields from the session or request type if needed.
+ - Applies optional help_text overrides for certain fields.
+ - Sends confirmation mail to the applicant.
+ - Sends notification mail to the internal IF address.
+ - Returns the "done" response after successful processing.
+ """
+ template_name = "input/forms/form_generic.html"
+ type_code: str = ""
def get_context_data(self, **kwargs):
- context = super().get_context_data(**kwargs)
- if hasattr(self, 'choice'):
- context["choice"] = TYPE_CHOICES[self.choice]
- return context
+ """Add the human-readable type string (from TYPE_CHOICES) to the template context."""
+ ctx = super().get_context_data(**kwargs)
+ ctx["typestring"] = TYPE_CHOICES.get(self.type_code, self.type_code)
+ return ctx
- def done(self, form_list, **kwargs):
- print('ExternView.done() reached')
- # gather data from all forms
- data = {}
- for form in form_list:
- data = {**data, **form.cleaned_data}
+ def get_form(self, form_class=None):
+ """Return the form instance and inject custom help_texts if defined for this type."""
+ form = super().get_form(form_class)
- if data['choice'] == 'LIT':
- if data['selfbuy'] == 'TRUE':
- data['selfbuy_give_data'] = 'False'
+ # Apply help_text overrides if defined for this type_code
+ if self.type_code in HELP_TEXTS:
+ for field, text in HELP_TEXTS[self.type_code].items():
+ if field in form.fields:
+ form.fields[field].help_text = mark_safe(text)
- # write data to database
+ return form
+
+ def form_valid(self, form):
+ """
+ Process a valid form submission:
+ - Enrich form data (e.g., set type_code, handle special rules).
+ - Save the model instance and related data.
+ - Send confirmation and notification mails.
+ - Return the "done" response.
+ """
+
+ # Collect cleaned data and mark the current type
+ data = form.cleaned_data.copy()
+ data["choice"] = self.type_code
+
+ # Special rule for literature applications
+ if self.type_code == "LIT" and data.get("selfbuy") == "TRUE":
+ data["selfbuy_give_data"] = "False"
+
+ # Save model instance
modell = form.save(commit=False)
- # we have to copy the data from the first form here
- # this is a bit ugly code. can we copy this without explicit writing?
- if data['choice'] == 'LIT':
- modell.selfbuy_give_data = data['selfbuy_give_data']
+ # Username from session if present
+ user = self.request.session.get("user")
+ if user:
+ modell.username = user.get("username")
- if user := self.request.session.get('user'):
- modell.username = user['username']
+ # Copy common fields if provided by the form
+ if "realname" in data:
+ modell.realname = data["realname"]
+ if "email" in data:
+ modell.email = data["email"]
- modell.realname = data['realname']
- modell.email = data['email']
- # write type of form in some cases
- if data['choice'] in ('BIB', 'ELIT', 'SOFT'):
- modell.type = data['choice']
+ # Set model.type for specific request types
+ if self.type_code in ("BIB", "ELIT", "SOFT"):
+ modell.type = self.type_code
- form.save()
+ # Literature-specific extra field
+ if self.type_code == "LIT" and "selfbuy_give_data" in data:
+ modell.selfbuy_give_data = data["selfbuy_give_data"]
- # add some data to context for mail templates
- data['pk'] = modell.pk
- data['url_prefix'] = settings.EMAIL_URL_PREFIX
- data['grant'] = ('LIT', 'SOFT', 'ELIT', 'BIB', 'IFG')
- data['DOMAIN'] = ('MAIL', 'LIST')
- data['typestring'] = TYPE_CHOICES[data['choice']]
+ modell.save()
+ if hasattr(form, "save_m2m"):
+ form.save_m2m()
+
+ # Prepare minimal mail context and send mails
+ data["pk"] = modell.pk
+ data["url_prefix"] = settings.EMAIL_URL_PREFIX
+ data["typestring"] = TYPE_CHOICES.get(self.type_code, self.type_code)
+ context = {"data": data}
- # we need to send the following mails here:
- context = { 'data': data }
try:
- # - mail with entered data to the Volunteer
-
- txt_mail_template1 = get_template('input/ifg_volunteer_mail.txt')
- html_mail_template1 = get_template('input/ifg_volunteer_mail.html')
-
- subject1, from_email1, to1 = 'Formular ausgefüllt', settings.IF_EMAIL, data['email']
- text_content1 = txt_mail_template1.render(context)
- html_content1 = html_mail_template1.render(context)
- msg1 = EmailMultiAlternatives(subject1, text_content1, from_email1, [to1])
- msg1.attach_alternative(html_content1, "text/html")
+ # Mail to applicant
+ txt1 = get_template("input/ifg_volunteer_mail.txt").render(context)
+ html1 = get_template("input/ifg_volunteer_mail.html").render(context)
+ msg1 = EmailMultiAlternatives(
+ "Formular ausgefüllt", txt1, settings.IF_EMAIL, [data["email"]]
+ )
+ msg1.attach_alternative(html1, "text/html")
msg1.send()
- #print('ifg volunteer mail would have been sent')
- #send_mail(
- # 'Formular ausgefüllt',
- # txt_mail_template1.render(context),
- # IF_EMAIL,
- # [data['email']],
- # fail_silently=False)
- ## - mail to IF with link to accept/decline
- txt_mail_template = get_template('input/if_mail.txt')
- html_mail_template = get_template('input/if_mail.html')
-
- subject, from_email, to = 'Formular ausgefüllt', settings.IF_EMAIL, settings.IF_EMAIL
- text_content = txt_mail_template.render(context)
- html_content = html_mail_template.render(context)
- msg2 = EmailMultiAlternatives(subject, text_content, from_email, [to])
- msg2.attach_alternative(html_content, "text/html")
+ # Mail to IF
+ txt2 = get_template("input/if_mail.txt").render(context)
+ html2 = get_template("input/if_mail.html").render(context)
+ msg2 = EmailMultiAlternatives(
+ "Formular ausgefüllt", txt2, settings.IF_EMAIL, [settings.IF_EMAIL]
+ )
+ msg2.attach_alternative(html2, "text/html")
msg2.send()
- #print('if mail would have been sent')
- #send_mail(
- # 'Formular ausgefüllt',
- # txt_mail_template.render(context),
- # IF_EMAIL,
- # [IF_EMAIL],
- # fail_silently=False)
- ## raise SMTPException("testing pupose only")
except BadHeaderError:
modell.delete()
- return HttpResponse('Invalid header found. Data not saved!')
+ return HttpResponse("Invalid header found. Data not saved!")
except SMTPException:
modell.delete()
- return HttpResponse('Error in sending mails (probably wrong adress?). Data not saved!')
-
+ return HttpResponse("Error in sending mails (probably wrong adress?). Data not saved!")
return done(self.request)
+
+
+class TravelApplicationView(BaseApplicationView):
+ form_class = TravelForm
+ type_code = "TRAV"
+
+
+class LibraryApplicationView(BaseApplicationView):
+ form_class = LibraryForm
+ type_code = "BIB"
+
+
+class ELiteratureApplicationView(BaseApplicationView):
+ form_class = ELiteratureForm
+ type_code = "ELIT"
+
+
+class SoftwareApplicationView(BaseApplicationView):
+ form_class = SoftwareForm
+ type_code = "SOFT"
+
+
+class IFGApplicationView(BaseApplicationView):
+ form_class = IFGForm
+ type_code = "IFG"
+
+
+class EmailApplicationView(BaseApplicationView):
+ form_class = EmailForm
+ type_code = "MAIL"
+
+
+class LiteratureApplicationView(BaseApplicationView):
+ form_class = LiteratureForm
+ type_code = "LIT"
+
+
+class ListApplicationView(BaseApplicationView):
+ form_class = ListForm
+ type_code = "LIST"
+
+
+class BusinessCardApplicationView(BaseApplicationView):
+ form_class = BusinessCardForm
+ type_code = "VIS"