我有一个Workshop
Django应用。每个Workshop
可以通过相关的WorkshopAttendee
模型(下面简化)有多个与会者。我在基于类的视图中使用Django的ModelForm
,在forms.py
我正在使用crispy-forms:
models.py(相关部分)
class Workshop(models.Model):
title = models.CharField(max_length=100)
information = models.TextField()
location = models.TextField()
class WorkshopAttendee(models.Model):
workshop = models.ForeignKey(Workshop)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
views.py(相关部分)
from django.views.generic.edit import FormView
from workshop.forms import WorkshopAttendeeForm
class WorkshopAttendeeFormView(FormView):
def form_valid(self, form):
# Clean the data
form_data = form.cleaned_data
form.save(commit=False)
return super(WorkshopAttendeeFormView, self).form_valid(form)
forms.py
from django.forms import ModelForm
from workshop.models import WorkshopAttendee
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, HTML, Field, \
Fieldset, Button, Hidden, Submit, Reset
from crispy_forms.bootstrap import FormActions
# Create the form class
class WorkshopAttendeeForm(ModelForm):
def __init__(self, *args, **kwargs):
# Crispy form Layouts, Fieldsets, etc
super(WorkshopAttendeeForm, self).__init__(*args, **kwargs)
class Meta:
model = WorkshopAttendee
urls.py(相关部分)
urlpatterns = patterns('',
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[\w\-.]+)/(?P<action>[\w\-.]+)/$',
WorkshopAttendeeFormView.as_view(
form_class=WorkshopAttendeeForm,
success_url="success/",
template_name='workshop/workshop_registration.html',
), name='workshop-attendee-register'
),
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[\w\-.]+)/$',
WorkshopDetailView.as_view(
context_object_name='workshop_detail',
queryset=Workshop.objects.select_related(),
template_name='workshop/workshop_detail.html',
), name='workshop-detail'
),
)
我的问题是,如何在隐藏的表单字段中使用 workshop_id (即FK关系)播种表单?显然因为表格还没有提交,所以还没有FK关系。但是在网址中,我有Workshop
slug 的 kwarg 。我可以在每个研讨会的基础上将workshop_id
硬编码为Hidden()
脆片形式字段,但这完全没有问题。有任何想法吗?我不认为我可以在 urls.py 中使用模型上的select_related()
或prefetch_related()
方法,所以也许我必须以某种方式将两个模型都放到表单视图中?
我觉得这不是一个边缘情况,我相信其他人也有类似的应用工作流程。
提前致谢。
更新
经过进一步研究后,似乎可以使用Django Formsets完成此操作。还没弄清楚究竟是怎么回事.....暗示欢迎。
答案 0 :(得分:2)
你不需要传递PK - 你已经在你的URL中将它作为slug。
所以我们假设这是您的网址:http://example.com/workshops/awesome-workshop-slug/sign_in/
您的urls.py
应如下所示:
url(r'^workshop/(?P<workshop_slug>\w+)/sign_in/$',
# ../workshops/awesome-workshop-slug/sign_in/
view = 'workshop_signin',
name = 'workshop-signin',
),
好的,在您的views.py
中,您可以执行此操作:
@login_required
def workshop_signin(request, workshop_slug, template='workshop/sign_in.html'):
"""Register user to workshop."""
form = WorkshopForm()
workshop = Workshop.objects.filter(slug=workshop_slug)[0]
if request.method == 'POST':
form = WorkshopForm(request.POST, instance=workshop)
if form.is_valid():
messages.info(request, 'Yay!')
kwargs = {
'workshop_form': form,
}
return render_to_response(template, kwargs, context_instance=RequestContext(request))
*未经测试的快速和脏代码
答案 1 :(得分:0)
事实证明我过于复杂了。
我需要做的就是将Django的GCBV form_valid
的{{1}}方法修改为:
<强>车间/ views.py 强>
FormView
这基本上不会在提交时保存表单,而是覆盖它并首先使用相关from django.views.generic.edit import FormView
from workshop.models import Workshop, WorkshopAttendee
from workshop.forms import WorkshopAttendeeForm
from django.http import HttpResponseRedirect
class WorkshopAttendeeFormView(FormView):
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.workshop = Workshop.objects.filter(slug=self.kwargs['slug'])[0]
self.object.save()
return HttpResponseRedirect(self.get_success_url())
更新要保存的对象(WorkshopAttendee
对象)(基于Workshop slug)字段,这是唯一的),然后保存更新的对象(Workshop
)并将我踢到成功网址。
非常感谢@ init3的有用指针。非常感谢。