I have a set of related models in a Django 1.5 app: Events
that have EventSessions
, and EventSessionRegistrations
that belong to EventSessions
.
I'm struggling to create a class based generic view for a user-facing registration form, where a user registers to attend an EventSession
. Specifically the problem is around excluding the field for which EventSession
the registration is for from being rendered in the form, whilst still setting that value based on the context and/or URL.
I'll try to explain via a use-case first:
- User goes to
'/events/foo/bar'
, wherefoo
is theEvent
, andbar
is theEventSession
. - At this URL, there is a link to register for the
EventSession
, leading to'/events/foo/bar/register/'
. Form for theEventSessionRegistration
model is displayed, but without selecting theEventSession
in the UI, since that information is already "set" by the URL. - After successful form submission, user is redirected to a static "Thanks"-page.
To acheive this, I have the following view code (lots of other imports etc excluded):
from django.views.generic.edit import CreateView
class RegistrationCreate(CreateView):
form_class = SessionRegistrationForm
success_url = '/thanks/'
template_name = 'events/registration_create.html'
def get_context_data(self, *args, **kwargs):
"""Set the context of which Event, and which EventSession.
Return 404 if either Event or EventSession is not public."""
context = super(RegistrationCreate, self).get_context_data(**kwargs)
s = get_object_or_404(
EventSession,
event__slug=self.kwargs['event_slug'],
event__is_public=True,
slug=self.kwargs['session_slug'],
is_public=True)
context['session'] = s
context['event'] = s.event
return context
URL pattern for this view (included from a base urls.py
):
url(r'^(?P<event_slug>[\w-]+)/(?P<session_slug>[\w-]+)/register/$',
RegistrationCreate.as_view(), name="event_session_registration"),
In the ModelForm, I've tried to convert the ForeignKey session
on EventSessionRegistration field (pointing to EventSession
) to show a HiddenInput()
-widget:
class SessionRegistrationForm(forms.ModelForm):
class Meta:
model = EventSessionRegistration
widgets = {
'session': HiddenInput()
}
But I still don't know how to set the initial value of that field to the id of the 'session'
value that I set in get_context_data
. I've tried setting self.initial = {'session': s.id}
inside get_context_data
, but I'm guessing that the initial
attribute is already used to construct the form at that point.
Any ideas on the best way to acheive this? What am I missing?