Make content submission form stuff much nicer. More DRY and more nice. Use one class with a form __init__ kwargs which sets eventtype

This commit is contained in:
Thomas Steen Rasmussen 2018-06-03 19:41:49 +02:00
parent 3180ec457d
commit 02a7af6303
3 changed files with 248 additions and 296 deletions

View file

@ -1,27 +1,132 @@
from django import forms import logging
from betterforms.multiform import MultiModelForm from betterforms.multiform import MultiModelForm
from collections import OrderedDict from collections import OrderedDict
from .models import SpeakerProposal, EventProposal, EventTrack
from django import forms
from django.forms.widgets import TextInput from django.forms.widgets import TextInput
from django.utils.dateparse import parse_duration from django.utils.dateparse import parse_duration
import logging
from .models import SpeakerProposal, EventProposal, EventTrack
logger = logging.getLogger("bornhack.%s" % __name__) logger = logging.getLogger("bornhack.%s" % __name__)
class BaseSpeakerProposalForm(forms.ModelForm): class SpeakerProposalForm(forms.ModelForm):
""" """
The BaseSpeakerProposalForm is not used directly. The SpeakerProposalForm. Takes an EventType in __init__ and changes fields accordingly.
It is subclassed for each eventtype, where fields are removed or get new labels and help_text as needed
""" """
class Meta: class Meta:
model = SpeakerProposal model = SpeakerProposal
fields = ['name', 'biography', 'needs_oneday_ticket', 'submission_notes'] fields = ['name', 'biography', 'needs_oneday_ticket', 'submission_notes']
def __init__(self, camp, eventtype=None, *args, **kwargs):
# initialise the form
super().__init__(*args, **kwargs)
class BaseEventProposalForm(forms.ModelForm): # adapt form based on EventType?
if not eventtype:
return
if eventtype.name == 'Debate':
# fix label and help_text for the name field
self.fields['name'].label = 'Guest Name'
self.fields['name'].help_text = 'The name of a debate guest. Can be a real name or an alias.'
# fix label and help_text for the biograpy field
self.fields['biography'].label = 'Guest Biography'
self.fields['biography'].help_text = 'The biography of the guest.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Guest Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this guest. Only visible to yourself and the BornHack organisers.'
# no free tickets for workshops
del(self.fields['needs_oneday_ticket'])
elif eventtype.name == 'Lightning Talk':
# fix label and help_text for the name field
self.fields['name'].label = 'Speaker Name'
self.fields['name'].help_text = 'The name of the speaker. Can be a real name or an alias.'
# fix label and help_text for the biograpy field
self.fields['biography'].label = 'Speaker Biography'
self.fields['biography'].help_text = 'The biography of the speaker.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Speaker Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this speaker. Only visible to yourself and the BornHack organisers.'
# no free tickets for lightning talks
del(self.fields['needs_oneday_ticket'])
elif eventtype.name == 'Music Act':
# fix label and help_text for the name field
self.fields['name'].label = 'Artist Name'
self.fields['name'].help_text = 'The name of the artist. Can be a real name or artist alias.'
# fix label and help_text for the biograpy field
self.fields['biography'].label = 'Artist Description'
self.fields['biography'].help_text = 'The description of the artist.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Artist Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this artist. Only visible to yourself and the BornHack organisers.'
# no oneday tickets for music acts
del(self.fields['needs_oneday_ticket'])
elif eventtype.name == 'Recreational Event':
# fix label and help_text for the name field
self.fields['name'].label = 'Host Name'
self.fields['name'].help_text = 'The name of the event host. Can be a real name or an alias.'
# fix label and help_text for the biograpy field
self.fields['biography'].label = 'Host Biography'
self.fields['biography'].help_text = 'The biography of the host.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Host Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this host. Only visible to yourself and the BornHack organisers.'
# no oneday tickets for music acts
del(self.fields['needs_oneday_ticket'])
elif eventtype.name == 'Talk':
# fix label and help_text for the name field
self.fields['name'].label = 'Speaker Name'
self.fields['name'].help_text = 'The name of the speaker. Can be a real name or an alias.'
# fix label and help_text for the biograpy field
self.fields['biography'].label = 'Speaker Biography'
self.fields['biography'].help_text = 'The biography of the speaker.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Speaker Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this speaker. Only visible to yourself and the BornHack organisers.'
elif eventtype.name == 'Workshop':
# fix label and help_text for the name field
self.fields['name'].label = 'Host Name'
self.fields['name'].help_text = 'The name of the workshop host. Can be a real name or an alias.'
# fix label and help_text for the biograpy field
self.fields['biography'].label = 'Host Biography'
self.fields['biography'].help_text = 'The biography of the host.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Host Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this host. Only visible to yourself and the BornHack organisers.'
# no free tickets for workshops
del(self.fields['needs_oneday_ticket'])
else:
raise ImproperlyConfigured("Unsupported event type, don't know which form class to use")
class EventProposalForm(forms.ModelForm):
""" """
The BaseEventProposalForm is not used directly. The EventProposalForm. Takes an EventType in __init__ and changes fields accordingly.
It is subclassed for each eventtype, where fields are removed or get new labels and help_text as needed
""" """
class Meta: class Meta:
model = EventProposal model = EventProposal
@ -38,234 +143,108 @@ class BaseEventProposalForm(forms.ModelForm):
# TODO: make sure the track is part of the current camp, needs camp as form kwarg to verify # TODO: make sure the track is part of the current camp, needs camp as form kwarg to verify
return track return track
def __init__(self, *args, **kwargs): def __init__(self, camp, eventtype=None, *args, **kwargs):
# initialise form
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# disable the empty_label for the track select box # disable the empty_label for the track select box
self.fields['track'].empty_label = None self.fields['track'].empty_label = None
self.fields['track'].queryset = EventTrack.objects.filter(camp=camp)
# make sure video_recording checkbox defaults to checked # make sure video_recording checkbox defaults to checked
self.fields['allow_video_recording'].initial = True self.fields['allow_video_recording'].initial = True
if eventtype.name == 'Debate':
# fix label and help_text for the title field
self.fields['title'].label = 'Title of debate'
self.fields['title'].help_text = 'The title of this debate'
################################ EventType "Talk" ################################################ # fix label and help_text for the abstract field
self.fields['abstract'].label = 'Description'
self.fields['abstract'].help_text = 'The description of this debate'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Debate Act Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this debate. Only visible to yourself and the BornHack organisers.'
class TalkEventProposalForm(BaseEventProposalForm): # better placeholder text for duration field
""" self.fields['duration'].widget.attrs['placeholder'] = 'Debate Duration (minutes)'
EventProposalForm with field names and help_text adapted to talk submissions
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# fix label and help_text for the title field elif eventtype.name == 'Music Act':
self.fields['title'].label = 'Title of Talk' # fix label and help_text for the title field
self.fields['title'].help_text = 'The title of this talk/presentation.' self.fields['title'].label = 'Title of music act'
self.fields['title'].help_text = 'The title of this music act/concert/set.'
# fix label and help_text for the abstract field # fix label and help_text for the abstract field
self.fields['abstract'].label = 'Abstract of Talk' self.fields['abstract'].label = 'Description'
self.fields['abstract'].help_text = 'The description/abstract of this talk/presentation. Explain what the audience will experience.' self.fields['abstract'].help_text = 'The description of this music act'
# fix label and help_text for the submission_notes field # fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Talk Notes' self.fields['submission_notes'].label = 'Music Act Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this talk. Only visible to yourself and the BornHack organisers.' self.fields['submission_notes'].help_text = 'Private notes regarding this music act. Only visible to yourself and the BornHack organisers.'
# no duration for talks # no video recording for music acts
del(self.fields['duration']) del(self.fields['allow_video_recording'])
# better placeholder text for duration field
self.fields['duration'].widget.attrs['placeholder'] = 'Duration (minutes)'
class TalkSpeakerProposalForm(BaseSpeakerProposalForm): elif eventtype.name == 'Recreational Event':
""" # fix label and help_text for the title field
SpeakerProposalForm with field labels and help_text adapted for talk submissions self.fields['title'].label = 'Event Title'
""" self.fields['title'].help_text = 'The title of this recreational event'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# fix label and help_text for the name field # fix label and help_text for the abstract field
self.fields['name'].label = 'Speaker Name' self.fields['abstract'].label = 'Event Abstract'
self.fields['name'].help_text = 'The name of the speaker. Can be a real name or an alias.' self.fields['abstract'].help_text = 'The description/abstract of this recreational event.'
# fix label and help_text for the biograpy field # fix label and help_text for the submission_notes field
self.fields['biography'].label = 'Speaker Biography' self.fields['submission_notes'].label = 'Event Notes'
self.fields['biography'].help_text = 'The biography of the speaker.' self.fields['submission_notes'].help_text = 'Private notes regarding this recreational event. Only visible to yourself and the BornHack organisers.'
# fix label and help_text for the submission_notes field # no video recording for music acts
self.fields['submission_notes'].label = 'Speaker Notes' del(self.fields['allow_video_recording'])
self.fields['submission_notes'].help_text = 'Private notes regarding this speaker. Only visible to yourself and the BornHack organisers.'
# better placeholder text for duration field
self.fields['duration'].label = 'Event Duration'
self.fields['duration'].widget.attrs['placeholder'] = 'Duration (minutes)'
################################ EventType "Lightning Talk" ################################################ elif eventtype.name == 'Talk' or eventtype.name == 'Lightning Talk':
# fix label and help_text for the title field
self.fields['title'].label = 'Title of Talk'
self.fields['title'].help_text = 'The title of this talk/presentation.'
# fix label and help_text for the abstract field
self.fields['abstract'].label = 'Abstract of Talk'
self.fields['abstract'].help_text = 'The description/abstract of this talk/presentation. Explain what the audience will experience.'
class LightningTalkEventProposalForm(TalkEventProposalForm): # fix label and help_text for the submission_notes field
""" self.fields['submission_notes'].label = 'Talk Notes'
LightningTalkEventProposalForm is identical to TalkEventProposalForm for now. Keeping the class here for easy customisation later. self.fields['submission_notes'].help_text = 'Private notes regarding this talk. Only visible to yourself and the BornHack organisers.'
"""
pass
class LightningTalkSpeakerProposalForm(TalkSpeakerProposalForm): # no duration for talks
""" del(self.fields['duration'])
LightningTalkSpeakerProposalForm is identical to TalkSpeakerProposalForm except for no free tickets
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# no free tickets for lightning talks elif eventtype.name == 'Workshop':
del(self.fields['needs_oneday_ticket']) # fix label and help_text for the title field
self.fields['title'].label = 'Workshop Title'
self.fields['title'].help_text = 'The title of this workshop.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Workshop Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this workshop. Only visible to yourself and the BornHack organisers.'
################################ EventType "Workshop" ################################################ # fix label and help_text for the abstract field
self.fields['abstract'].label = 'Workshop Abstract'
self.fields['abstract'].help_text = 'The description/abstract of this workshop. Explain what the participants will learn.'
# no video recording for workshops
del(self.fields['allow_video_recording'])
class WorkshopEventProposalForm(BaseEventProposalForm): # duration field
""" self.fields['duration'].label = 'Workshop Duration'
EventProposalForm with field names and help_text adapted for workshop submissions self.fields['duration'].help_text = 'How much time (in minutes) should we set aside for this workshop? Please keep it between 60 and 180 minutes (1-3 hours).'
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# fix label and help_text for the title field else:
self.fields['title'].label = 'Workshop Title' raise ImproperlyConfigured("Unsupported event type, don't know which form class to use")
self.fields['title'].help_text = 'The title of this workshop.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Workshop Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this workshop. Only visible to yourself and the BornHack organisers.'
# fix label and help_text for the abstract field
self.fields['abstract'].label = 'Workshop Abstract'
self.fields['abstract'].help_text = 'The description/abstract of this workshop. Explain what the participants will learn.'
# no video recording for workshops
del(self.fields['allow_video_recording'])
# duration field
self.fields['duration'].label = 'Workshop Duration'
self.fields['duration'].help_text = 'How much time (in minutes) should we set aside for this workshop? Please keep it between 60 and 180 minutes (1-3 hours).'
class WorkshopSpeakerProposalForm(BaseSpeakerProposalForm):
"""
SpeakerProposalForm with field labels and help_text adapted for workshop submissions
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# fix label and help_text for the name field
self.fields['name'].label = 'Host Name'
self.fields['name'].help_text = 'The name of the workshop host. Can be a real name or an alias.'
# fix label and help_text for the biograpy field
self.fields['biography'].label = 'Host Biography'
self.fields['biography'].help_text = 'The biography of the host.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Host Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this host. Only visible to yourself and the BornHack organisers.'
# no free tickets for workshops
del(self.fields['needs_oneday_ticket'])
################################ EventType "Music" ################################################
class MusicEventProposalForm(BaseEventProposalForm):
"""
EventProposalForm with field names and help_text adapted to music submissions
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# fix label and help_text for the title field
self.fields['title'].label = 'Title of music act'
self.fields['title'].help_text = 'The title of this music act/concert/set.'
# fix label and help_text for the abstract field
self.fields['abstract'].label = 'Description'
self.fields['abstract'].help_text = 'The description of this music act'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Music Act Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this music act. Only visible to yourself and the BornHack organisers.'
# no video recording for music acts
del(self.fields['allow_video_recording'])
# better placeholder text for duration field
self.fields['duration'].widget.attrs['placeholder'] = 'Duration (minutes)'
class MusicSpeakerProposalForm(BaseSpeakerProposalForm):
"""
SpeakerProposalForm with field labels and help_text adapted for music submissions
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# fix label and help_text for the name field
self.fields['name'].label = 'Artist Name'
self.fields['name'].help_text = 'The name of the artist. Can be a real name or artist alias.'
# fix label and help_text for the biograpy field
self.fields['biography'].label = 'Artist Description'
self.fields['biography'].help_text = 'The description of the artist.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Artist Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this artist. Only visible to yourself and the BornHack organisers.'
# no oneday tickets for music acts
del(self.fields['needs_oneday_ticket'])
################################ EventType "Slacking Off" ################################################
class SlackEventProposalForm(BaseEventProposalForm):
"""
EventProposalForm with field names and help_text adapted to slacking off submissions
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# fix label and help_text for the title field
self.fields['title'].label = 'Event Title'
self.fields['title'].help_text = 'The title of this recreational event'
# fix label and help_text for the abstract field
self.fields['abstract'].label = 'Event Abstract'
self.fields['abstract'].help_text = 'The description/abstract of this recreational event.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Event Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this recreational event. Only visible to yourself and the BornHack organisers.'
# no video recording for music acts
del(self.fields['allow_video_recording'])
# better placeholder text for duration field
self.fields['duration'].label = 'Event Duration'
self.fields['duration'].widget.attrs['placeholder'] = 'Duration (minutes)'
class SlackSpeakerProposalForm(BaseSpeakerProposalForm):
"""
SpeakerProposalForm with field labels and help_text adapted for recreational events
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# fix label and help_text for the name field
self.fields['name'].label = 'Host Name'
self.fields['name'].help_text = 'The name of the event host. Can be a real name or an alias.'
# fix label and help_text for the biograpy field
self.fields['biography'].label = 'Host Biography'
self.fields['biography'].help_text = 'The biography of the host.'
# fix label and help_text for the submission_notes field
self.fields['submission_notes'].label = 'Host Notes'
self.fields['submission_notes'].help_text = 'Private notes regarding this host. Only visible to yourself and the BornHack organisers.'
# no oneday tickets for music acts
del(self.fields['needs_oneday_ticket'])

View file

@ -1,38 +0,0 @@
from django.core.exceptions import ImproperlyConfigured
from .forms import *
def get_speakerproposal_form_class(eventtype):
"""
Return a SpeakerProposal form class suitable for the provided EventType
"""
if eventtype.name == 'Music Act':
return MusicSpeakerProposalForm
elif eventtype.name == 'Talk':
return TalkSpeakerProposalForm
elif eventtype.name == 'Workshop':
return WorkshopSpeakerProposalForm
elif eventtype.name == 'Lightning Talk':
return LightningTalkSpeakerProposalForm
elif eventtype.name == 'Recreational Event':
return SlackSpeakerProposalForm
else:
raise ImproperlyConfigured("Unsupported event type, don't know which form class to use")
def get_eventproposal_form_class(eventtype):
"""
Return an EventProposal form class suitable for the provided EventType
"""
if eventtype.name == 'Music Act':
return MusicEventProposalForm
elif eventtype.name == 'Talk':
return TalkEventProposalForm
elif eventtype.name == 'Workshop':
return WorkshopEventProposalForm
elif eventtype.name == 'Lightning Talk':
return LightningTalkEventProposalForm
elif eventtype.name == 'Recreational Event':
return SlackEventProposalForm
else:
raise ImproperlyConfigured("Unsupported event type, don't know which form class to use")

View file

@ -34,8 +34,7 @@ from .email import (
add_eventproposal_updated_email add_eventproposal_updated_email
) )
from . import models from . import models
from .utils import get_speakerproposal_form_class, get_eventproposal_form_class from .forms import SpeakerProposalForm, EventProposalForm
from .forms import BaseSpeakerProposalForm
logger = logging.getLogger("bornhack.%s" % __name__) logger = logging.getLogger("bornhack.%s" % __name__)
@ -129,6 +128,7 @@ class SpeakerProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritabl
""" This view allows a user to create a new SpeakerProposal linked to an existing EventProposal """ """ This view allows a user to create a new SpeakerProposal linked to an existing EventProposal """
model = models.SpeakerProposal model = models.SpeakerProposal
template_name = 'speakerproposal_form.html' template_name = 'speakerproposal_form.html'
form_class = SpeakerProposalForm
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
""" Get the eventproposal object """ """ Get the eventproposal object """
@ -138,8 +138,16 @@ class SpeakerProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritabl
def get_success_url(self): def get_success_url(self):
return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}) return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})
def get_form_class(self): def get_form_kwargs(self):
return get_speakerproposal_form_class(eventtype=self.eventproposal.event_type) """
Set camp and eventtype for the form
"""
kwargs = super().get_form_kwargs()
kwargs.update({
'camp': self.camp,
'eventtype': self.eventproposal.event_type
})
return kwargs
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
@ -170,22 +178,34 @@ class SpeakerProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritabl
""" """
model = models.SpeakerProposal model = models.SpeakerProposal
template_name = 'speakerproposal_form.html' template_name = 'speakerproposal_form.html'
form_class = SpeakerProposalForm
def get_form_kwargs(self):
def get_form_class(self): """
""" Get the appropriate form class based on the eventtype """ Set camp and eventtype for the form
"""
kwargs = super().get_form_kwargs()
if self.get_object().eventproposals.count() == 1: if self.get_object().eventproposals.count() == 1:
# determine which form to use based on the type of event associated with the proposal # determine which form to use based on the type of event associated with the proposal
return get_speakerproposal_form_class(self.get_object().eventproposals.get().event_type) eventtype = self.get_object().eventproposals.get().event_type
else: else:
# more than one eventproposal. If all events are the same type we can still show a non-generic form here # more than one eventproposal. If all events are the same type we can still show a non-generic form here
eventtypes = set() eventtypes = set()
for ep in self.get_object().eventproposals.all(): for ep in self.get_object().eventproposals.all():
eventtypes.add(ep.event_type) eventtypes.add(ep.event_type)
if len(eventtypes) == 1: if len(eventtypes) == 1:
return get_speakerproposal_form_class(ep.event_type) eventtype = self.get_object().eventproposals.get().event_type
# more than one type of event for this person, return the generic speakerproposal form else:
return BaseSpeakerProposalForm # more than one type of event for this person, return the generic speakerproposal form
eventtype = None
# add camp and eventtype to form kwargs
kwargs.update({
'camp': self.camp,
'eventtype': eventtype
})
return kwargs
def form_valid(self, form): def form_valid(self, form):
""" """
@ -365,10 +385,7 @@ class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC
""" """
model = models.EventProposal model = models.EventProposal
template_name = 'eventproposal_form.html' template_name = 'eventproposal_form.html'
form_class = EventProposalForm
def get_form_class(self):
""" Get the appropriate form class based on the eventtype """
return get_eventproposal_form_class(self.event_type)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
""" Get the speakerproposal object """ """ Get the speakerproposal object """
@ -383,16 +400,16 @@ class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC
context['event_type'] = self.event_type context['event_type'] = self.event_type
return context return context
def get_form(self): def get_form_kwargs(self):
""" """
Override get_form() method so we can set the queryset for the track selector. Set camp and eventtype for the form
Usually this kind of thing would go into get_initial() but that does not work for some reason, so we do it here instead.
""" """
form_class = self.get_form_class() kwargs = super().get_form_kwargs()
form = form_class(**self.get_form_kwargs()) kwargs.update({
form.fields['track'].queryset = models.EventTrack.objects.filter(camp=self.camp) 'camp': self.camp,
return form 'eventtype': self.event_type
})
return kwargs
def form_valid(self, form): def form_valid(self, form):
# set camp and user for this eventproposal # set camp and user for this eventproposal
@ -418,11 +435,18 @@ class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC
class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureUserOwnsProposalMixin, EnsureCFPOpenMixin, UpdateView): class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureUserOwnsProposalMixin, EnsureCFPOpenMixin, UpdateView):
model = models.EventProposal model = models.EventProposal
template_name = 'eventproposal_form.html' template_name = 'eventproposal_form.html'
form_class = EventProposalForm
def get_form_class(self): def get_form_kwargs(self):
""" Get the appropriate form class based on the eventtype """ """
return get_eventproposal_form_class(self.get_object().event_type) Set camp and eventtype for the form
"""
kwargs = super().get_form_kwargs()
kwargs.update({
'camp': self.camp,
'eventtype': self.get_object().event_type
})
return kwargs
def get_context_data(self, *args, **kwargs): def get_context_data(self, *args, **kwargs):
""" Make speakerproposal and eventtype objects available in the template """ """ Make speakerproposal and eventtype objects available in the template """
@ -430,16 +454,6 @@ class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC
context['event_type'] = self.get_object().event_type context['event_type'] = self.get_object().event_type
return context return context
def get_form(self):
"""
Override get_form() method so we can set the queryset for the track selector.
Usually this kind of thing would go into get_initial() but that does not work for some reason, so we do it here instead.
"""
form_class = self.get_form_class()
form = form_class(**self.get_form_kwargs())
form.fields['track'].queryset = models.EventTrack.objects.filter(camp=self.camp)
return form
def form_valid(self, form): def form_valid(self, form):
# set status to pending and save eventproposal # set status to pending and save eventproposal
form.instance.proposal_status = models.EventProposal.PROPOSAL_PENDING form.instance.proposal_status = models.EventProposal.PROPOSAL_PENDING
@ -588,11 +602,7 @@ class CombinedProposalSubmitView(LoginRequiredMixin, CampViewMixin, CreateView):
""" """
if hasattr(self, 'speakerproposal'): if hasattr(self, 'speakerproposal'):
# we already have a speakerproposal, just show an eventproposal form # we already have a speakerproposal, just show an eventproposal form
return get_eventproposal_form_class(eventtype=self.eventtype) return EventProposalForm
# get the two forms we need to build the MultiModelForm
SpeakerProposalForm = get_speakerproposal_form_class(eventtype=self.eventtype)
EventProposalForm = get_eventproposal_form_class(eventtype=self.eventtype)
# build our MultiModelForm # build our MultiModelForm
class CombinedProposalSubmitForm(MultiModelForm): class CombinedProposalSubmitForm(MultiModelForm):
@ -604,15 +614,16 @@ class CombinedProposalSubmitView(LoginRequiredMixin, CampViewMixin, CreateView):
# return the form class # return the form class
return CombinedProposalSubmitForm return CombinedProposalSubmitForm
def get_form(self): def get_form_kwargs(self):
""" """
Override get_form() method so we can set the queryset for the track selector. Set camp and eventtype for the form
Usually this kind of thing would go into get_initial() but that does not work for some reason, so we do it here instead.
""" """
form_class = self.get_form_class() kwargs = super().get_form_kwargs()
form = form_class(**self.get_form_kwargs()) kwargs.update({
form.forms['eventproposal'].fields['track'].queryset = models.EventTrack.objects.filter(camp=self.camp) 'camp': self.camp,
return form 'eventtype': self.eventtype
})
return kwargs
################################################################################################### ###################################################################################################