0

我在 Django 1.5 应用程序中有一组相关模型:Events具有EventSessionsEventSessionRegistrations属于EventSessions.

我正在努力为面向用户的注册表单创建一个基于类的通用视图,用户在其中注册以参加EventSession. 具体来说,问题在于排除EventSession在表单中呈现注册的字段,同时仍根据上下文和/或 URL 设置该值。

我将首先尝试通过一个用例进行解释:

  1. 用户去了'/events/foo/bar'fooEventbarEventSession
  2. 在这个 URL 上,有一个注册 的链接EventSession,指向'/events/foo/bar/register/'. 显示模型的表单EventSessionRegistration,但未EventSession在 UI 中选择 ,因为该信息已由 URL“设置”。
  3. 成功提交表单后,用户被重定向到静态“感谢”页面。

为了实现这一点,我有以下视图代码(许多其他导入等除外):

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 模式(包含在 base 中urls.py):

url(r'^(?P<event_slug>[\w-]+)/(?P<session_slug>[\w-]+)/register/$',
    RegistrationCreate.as_view(), name="event_session_registration"),

在 ModelForm 中,我尝试将sessionEventSessionRegistration 字段(指向EventSession)上的 ForeignKey 转换为显示HiddenInput()-widget:

class SessionRegistrationForm(forms.ModelForm):

    class Meta:
        model = EventSessionRegistration
        widgets = {
            'session': HiddenInput()
        }

但是我仍然不知道如何将该字段的初始值设置为'session'我设置的值的 id get_context_data。我试过self.initial = {'session': s.id}在里面设置get_context_data,但我猜这个initial属性已经被用来构造表单了。

关于实现这一目标的最佳方法的任何想法?我错过了什么?

4

1 回答 1

2

是的,我找到了这个问题,它涉及相同的问题。我最终在视图中使用了以下覆盖后的函数,并在隐藏字段中手动输出模板中的会话 ID:

def post(self, request, *args, **kwargs):
    self.object = None
    evt_session = get_object_or_404(
        EventSession, pk=int(self.request.POST['session']))
    form_class = self.get_form_class()
    form = self.get_form(form_class)

    form.instance.session = evt_session

    if form.is_valid():
        return self.form_valid(form)
    else:
        return self.form_invalid(form)

此外,我还找到了 ccbv.co.uk,这是一个很好的资源,可用于了解 CBV:s 中的所有方法和属性,它为如何构建覆盖提供了指导。

于 2013-06-28T11:14:58.050 回答