gpt4 book ai didi

带有自定义表单的 django 内联表单

转载 作者:行者123 更新时间:2023-12-04 17:27:51 26 4
gpt4 key购买 nike

你好
我有一个在 Django 应用程序中使用的域模型,我想在一个表单上呈现它。我已经使用自定义 ModelForms 创建了我的应用程序(没有太大变化,排除了一些字段等)。模型的依赖关系如下:

Complaint
\
.--- CarInfo
.--- Customer

我的 View 函数如下所示:
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})

我不太喜欢这种方法,而且它并不适用于所有环境——我还没有找到它不起作用的原因。我一直在研究修复此代码,发现类似于 内联表单集 (http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets)。这个解决方案看起来不错,但由于我的表格是定制的,我可以使用它。

也许有人可以就如何正确解决这种情况给我一些建议。更清洁的解决方案非常受欢迎。

已编辑
对我来说有一个案例,这个解决方案不起作用。尽管在外键上设置了虚拟值,但当我调用 is_valid() 时,我得到 FALSE,错误消息指出这些字段未设置。我用 django 1.2.5 观察到这个问题 - 它发生在我打算运行这个应用程序的服务器上,但是我的笔记本电脑(也是 django 1.2.5)没有这个问题。

最佳答案

您可以将您的投诉模型的投诉日期更改为这样的
complaint_date = models.DateField(default=datetime.date.today())
这样你就可以摆脱
parameters['complaint_date'] = get_current_date()
至于您的多表单 View ,您可以使用未绑定(bind)的表单来实现所需的行为。

通过在投诉表格上排除对汽车和客户的 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))

编辑:

模型如下所示:
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()

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',)

让我们看看我上面写的 View :
form in view docs
  • 在第一次通过时,没有 request.method 所以我们创建 3 unbound形式。
    else:
    form = ComplaintForm()
    carInfo_form = CarInfoForm()
    customer_form = CustomerForm()
  • 这些表单被传递给模板并呈现。
  • 当使用 request.method == "POST"评估 true 再次调用 View 时,我们使用 request.POST 中的数据创建 3 个绑定(bind)表单实例。
    if request.method == 'POST':
    customer_form = CustomerForm(request.POST)
    carInfo_form = CarInfoForm(request.POST)
    form = ComplaintForm(request.POST)
  • 接下来我们在每个 上调用 .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()
  • 使用这两种形式,我们可以像往常一样调用 .save() 。然而,我们会将返回值分配给 car_instance 和 customer_instance。这些将包含我们刚刚使用表单上的 .save() 方法创建的 CarInfo 和 Customer 模型的实例。
  • 接下来,使用 commit=False .save() 方法中的参数,我们能够从绑定(bind)的表单(包含 request.POST 数据)创建一个对象,而不是将其保存到数据库中。
            complaint_instance = form.save(commit=False)
    complaint_instance.car_info = car_instance
    complaint_instance.customer_info = customer_instance
    complaint_instance.save()
  • 为了更清楚地说明这一点,您还可以像这样创建一个新的 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()
  • 渲染
  • 关于带有自定义表单的 django 内联表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5171365/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com