Mar*_*lke 5 django django-forms
嗨,我有一个领域模型,用于Django应用程序,我想在一个表单上呈现.我用自定义的ModelForms创建了我的应用程序(没有太多变化,一些字段被排除在外等).模型的依赖关系如下:
Complaint
\
.--- CarInfo
.--- Customer
Run Code Online (Sandbox Code Playgroud)
我的视图功能如下所示:
def make(request):
if request.method == 'POST':
parameters = copy.copy(request.POST)
complaint = Complaint()
carInfo = CarInfo()
customer = Customer()
customer_form = CustomerForm(parameters, instance=customer)
carInfo_form = CarInfoForm(parameters, instance=carInfo)
parameters['complaint_date'] = get_current_date()
parameters['customer'] = 1 # dummy value to allow validation success
parameters['car_info'] = 1 # dummy value to allow validation success
form = ComplaintForm(parameters, instance=complaint)
if form.is_valid() and customer_form.is_valid() and carInfo_form.is_valid():
carInfo_form.save()
customer_form.save()
parameters['customer'] = customer.id
parameters['car_info'] = carInfo.id
form = ComplaintForm(parameters, instance=complaint)
form.save()
return index(request)
else:
form = ComplaintForm()
carInfo_form = CarInfoForm()
customer_form = CustomerForm()
return render_to_response('complaints/make_complaint.html', {'complaint_form' : form, 'customer_form' : customer_form, 'carInfo' : carInfo_form})
Run Code Online (Sandbox Code Playgroud)
我不太喜欢这种方法,而且它并不适用于所有环境 - 你还没有找到它不起作用的原因.我一直在研究修改这段代码并找到类似内联formset的内容(http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets).这个解决方案似乎没问题,但由于我的表单是定制的,我可以使用它.
也许有人可以就如何妥善解决此类案件提供一些建议.非常感谢清洁解决方案.
编辑 我有一个案例,这个解决方案不起作用.尽管在外键上设置了虚拟值,但当我调用is_valid()时,我得到FALSE,并显示错误消息,指出这些字段未设置.我正在用django 1.2.5观察这个问题 - 它发生在服务器上我打算运行这个应用程序,但是我的笔记本电脑(也是django 1.2.5)没有这个问题.
您可以将Complaint模型的complaint_date更改为此类似的内容
complaint_date = models.DateField(default=datetime.date.today())
这样你就可以摆脱
parameters['complaint_date'] = get_current_date()
对于您的多形式视图,您可以使用未绑定的表单来实现所需的行为.
通过在投诉表格中将fk排除给汽车和客户,表格应该验证.同时检查所有3个表单的.is_valid(),然后保存投诉对象所依赖的2个表单,创建投诉对象,不提交数据库(commit = False),添加客户的id和汽车到那个对象,然后保存.
在你看来.
def make(request):
if request.method == 'POST':
customer_form = CustomerForm(request.POST)
carInfo_form = CarInfoForm(request.POST)
form = ComplaintForm(request.POST)
if form.is_valid() and customer_form.is_valid() and carInfo_form.is_valid():
car_instance = carInfo_form.save()
customer_instance = customer_form.save()
complaint_instance = form.save(commit=False)
complaint_instance.car_info = car_instance
complaint_instance.customer_info = customer_instance
complaint_instance.save()
return index(request)
else:
form = ComplaintForm()
carInfo_form = CarInfoForm()
customer_form = CustomerForm()
context = { 'complaint_form' : form,
'customer_form' : customer_form,
'carInfo' : carInfo_form,
}
return render_to_response('complaints/make_complaint.html', context, context_instance=RequestContext(request))
Run Code Online (Sandbox Code Playgroud)
编辑:
模型看起来像这样:
class CarInfo(models.Model):
some_car_info = models.CharField()
class Customer(models.Model):
some_customer_info = models.CharField()
class Complaint(models.Model):
car_info = models.ForeignKey(CarInfo)
customer_info = models.ForeignKey(Customer)
some_complaint_info = models.CharField()
Run Code Online (Sandbox Code Playgroud)
forms.py应如下所示:
class CarInfoForm(forms.ModelForm):
class Meta:
model = CarInfo
class CustomerForm(forms.ModelForm):
class Meta:
model = Customer
class ComplaintForm(forms.ModelForm):
class Meta:
model = Complaint
exclude = ('car_info', 'customer_info',) # or include = ('some_complaint_info',)
Run Code Online (Sandbox Code Playgroud)
让我们来看看上面写的视图:
form in view docs
在第一次传递时,没有request.method所以我们创建了3个未绑定的表单.
else:
form = ComplaintForm()
carInfo_form = CarInfoForm()
customer_form = CustomerForm()
Run Code Online (Sandbox Code Playgroud)这些表单将传递给模板并进行渲染.
当request.method =="POST"评估为true时再次调用视图时,我们使用request.POST中的数据创建3个绑定表单实例.
if request.method == 'POST':
customer_form = CustomerForm(request.POST)
carInfo_form = CarInfoForm(request.POST)
form = ComplaintForm(request.POST)
Run Code Online (Sandbox Code Playgroud)接下来,我们在每个表单上调用.is_valid()方法.在我们的示例中,因为我们在投诉模型中排除了'customer_info'和'car_info'外键字段,所以每个表单只检查char输入字段是否有效.
如果验证全部通过,那么我们可以开始将表单保存到模型中,我们需要注意填写我们的投诉所需的fk:
if form.is_valid() and customer_form.is_valid() and carInfo_form.is_valid():
car_instance = carInfo_form.save()
customer_instance = customer_form.save()
Run Code Online (Sandbox Code Playgroud)使用这两种形式,我们可以像往常一样调用.save().但是,我们会将返回值分配给car_instance和customer_instance.这些将包含我们刚刚使用表单上的.save()方法创建的CarInfo和Customer模型的实例.
接下来,使用commit=False.save()方法中的参数,我们能够从绑定表单(包含request.POST数据)创建一个对象,而不是将其保存到数据库中.
complaint_instance = form.save(commit=False)
complaint_instance.car_info = car_instance
complaint_instance.customer_info = customer_instance
complaint_instance.save()
Run Code Online (Sandbox Code Playgroud)为了更清楚,您还可以创建一个新的Complaint对象,如下所示:
complaint_info = form.cleaned_data.get('some_complaint_info')
complaint_instance = Complaint(car_info=car_instance, customer_info=customer_instance, some_complaint_info=some_complaint_info)
complaint_instance.save()
Run Code Online (Sandbox Code Playgroud)给予
| 归档时间: |
|
| 查看次数: |
7851 次 |
| 最近记录: |