forked from beba/foerderbarometer
refactor ExternView into separate class-based views with BaseApplicationView
This commit is contained in:
parent
98d1ae9284
commit
7cfd477d40
271
input/views.py
271
input/views.py
|
|
@ -8,6 +8,7 @@ from django.core.mail import BadHeaderError, EmailMultiAlternatives
|
||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.views.generic.edit import FormView
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
ExternForm,
|
ExternForm,
|
||||||
|
|
@ -29,6 +30,30 @@ LIBRARY_FORMS = {
|
||||||
TYPE_SOFT: SoftwareForm,
|
TYPE_SOFT: SoftwareForm,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HELP_TEXTS = {
|
||||||
|
"IFG": {
|
||||||
|
"notes": (
|
||||||
|
"Bitte gib an, wie die gewonnenen Informationen den<br>"
|
||||||
|
"Wikimedia-Projekten zugute kommen sollen."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"MAIL": {
|
||||||
|
"domain": (
|
||||||
|
"Mit welcher Domain, bzw. für welches Wikimedia-Projekt,<br>"
|
||||||
|
"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,<br>"
|
||||||
|
"möchtest du eine Mailingliste beantragen?"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def auth_deny(choice, pk, auth):
|
def auth_deny(choice, pk, auth):
|
||||||
if choice not in MODELS:
|
if choice not in MODELS:
|
||||||
|
|
@ -66,146 +91,166 @@ def deny(request, choice, pk):
|
||||||
|
|
||||||
|
|
||||||
def done(request):
|
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):
|
def index(request):
|
||||||
return render(request, 'input/index.html')
|
return render(request, 'input/index.html')
|
||||||
|
|
||||||
|
|
||||||
class ExternView(CookieWizardView):
|
class BaseApplicationView(FormView):
|
||||||
'''This View is for Volunteers'''
|
"""
|
||||||
|
Base view for all application types.
|
||||||
|
|
||||||
template_name = "input/extern.html"
|
- Each application type (travel, literature, email, etc.) gets its own subclass.
|
||||||
form_list = [ExternForm, LibraryForm]
|
- Renders the generic form template.
|
||||||
|
- Handles saving the submitted form to the database.
|
||||||
def get_form(self, step=None, data=None, files=None):
|
- Adds extra fields from the session or request type if needed.
|
||||||
'''this function determines which part of the multipart form is
|
- Applies optional help_text overrides for certain fields.
|
||||||
displayed next'''
|
- Sends confirmation mail to the applicant.
|
||||||
|
- Sends notification mail to the internal IF address.
|
||||||
if step is None:
|
- Returns the "done" response after successful processing.
|
||||||
step = self.steps.current
|
"""
|
||||||
print ("get_form() step " + step)
|
template_name = "input/forms/form_generic.html"
|
||||||
|
type_code: str = ""
|
||||||
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<br>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,<br>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,<br>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
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
"""Add the human-readable type string (from TYPE_CHOICES) to the template context."""
|
||||||
if hasattr(self, 'choice'):
|
ctx = super().get_context_data(**kwargs)
|
||||||
context["choice"] = TYPE_CHOICES[self.choice]
|
ctx["typestring"] = TYPE_CHOICES.get(self.type_code, self.type_code)
|
||||||
return context
|
return ctx
|
||||||
|
|
||||||
def done(self, form_list, **kwargs):
|
def get_form(self, form_class=None):
|
||||||
print('ExternView.done() reached')
|
"""Return the form instance and inject custom help_texts if defined for this type."""
|
||||||
# gather data from all forms
|
form = super().get_form(form_class)
|
||||||
data = {}
|
|
||||||
for form in form_list:
|
|
||||||
data = {**data, **form.cleaned_data}
|
|
||||||
|
|
||||||
if data['choice'] == 'LIT':
|
# Apply help_text overrides if defined for this type_code
|
||||||
if data['selfbuy'] == 'TRUE':
|
if self.type_code in HELP_TEXTS:
|
||||||
data['selfbuy_give_data'] = 'False'
|
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)
|
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':
|
# Username from session if present
|
||||||
modell.selfbuy_give_data = data['selfbuy_give_data']
|
user = self.request.session.get("user")
|
||||||
|
if user:
|
||||||
|
modell.username = user.get("username")
|
||||||
|
|
||||||
if user := self.request.session.get('user'):
|
# Copy common fields if provided by the form
|
||||||
modell.username = user['username']
|
if "realname" in data:
|
||||||
|
modell.realname = data["realname"]
|
||||||
|
if "email" in data:
|
||||||
|
modell.email = data["email"]
|
||||||
|
|
||||||
modell.realname = data['realname']
|
# Set model.type for specific request types
|
||||||
modell.email = data['email']
|
if self.type_code in ("BIB", "ELIT", "SOFT"):
|
||||||
# write type of form in some cases
|
modell.type = self.type_code
|
||||||
if data['choice'] in ('BIB', 'ELIT', 'SOFT'):
|
|
||||||
modell.type = data['choice']
|
|
||||||
|
|
||||||
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
|
modell.save()
|
||||||
data['pk'] = modell.pk
|
if hasattr(form, "save_m2m"):
|
||||||
data['url_prefix'] = settings.EMAIL_URL_PREFIX
|
form.save_m2m()
|
||||||
data['grant'] = ('LIT', 'SOFT', 'ELIT', 'BIB', 'IFG')
|
|
||||||
data['DOMAIN'] = ('MAIL', 'LIST')
|
# Prepare minimal mail context and send mails
|
||||||
data['typestring'] = TYPE_CHOICES[data['choice']]
|
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:
|
try:
|
||||||
# - mail with entered data to the Volunteer
|
# Mail to applicant
|
||||||
|
txt1 = get_template("input/ifg_volunteer_mail.txt").render(context)
|
||||||
txt_mail_template1 = get_template('input/ifg_volunteer_mail.txt')
|
html1 = get_template("input/ifg_volunteer_mail.html").render(context)
|
||||||
html_mail_template1 = get_template('input/ifg_volunteer_mail.html')
|
msg1 = EmailMultiAlternatives(
|
||||||
|
"Formular ausgefüllt", txt1, settings.IF_EMAIL, [data["email"]]
|
||||||
subject1, from_email1, to1 = 'Formular ausgefüllt', settings.IF_EMAIL, data['email']
|
)
|
||||||
text_content1 = txt_mail_template1.render(context)
|
msg1.attach_alternative(html1, "text/html")
|
||||||
html_content1 = html_mail_template1.render(context)
|
|
||||||
msg1 = EmailMultiAlternatives(subject1, text_content1, from_email1, [to1])
|
|
||||||
msg1.attach_alternative(html_content1, "text/html")
|
|
||||||
msg1.send()
|
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')
|
# Mail to IF
|
||||||
html_mail_template = get_template('input/if_mail.html')
|
txt2 = get_template("input/if_mail.txt").render(context)
|
||||||
|
html2 = get_template("input/if_mail.html").render(context)
|
||||||
subject, from_email, to = 'Formular ausgefüllt', settings.IF_EMAIL, settings.IF_EMAIL
|
msg2 = EmailMultiAlternatives(
|
||||||
text_content = txt_mail_template.render(context)
|
"Formular ausgefüllt", txt2, settings.IF_EMAIL, [settings.IF_EMAIL]
|
||||||
html_content = html_mail_template.render(context)
|
)
|
||||||
msg2 = EmailMultiAlternatives(subject, text_content, from_email, [to])
|
msg2.attach_alternative(html2, "text/html")
|
||||||
msg2.attach_alternative(html_content, "text/html")
|
|
||||||
msg2.send()
|
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:
|
except BadHeaderError:
|
||||||
modell.delete()
|
modell.delete()
|
||||||
return HttpResponse('Invalid header found. Data not saved!')
|
return HttpResponse("Invalid header found. Data not saved!")
|
||||||
except SMTPException:
|
except SMTPException:
|
||||||
modell.delete()
|
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)
|
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"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue