Gar*_*nzo 14 django django-forms django-class-based-views
我有一个Expense
模型和一个ExpenseLineItem
模型.就像典型的费用/发票一样,一个费用可以有多个行项目来弥补发票的总成本.我正在尝试使用基于类的视图来创建和更新费用.我已成功编码CreateView
以使用多个费用订单项进行新费用.
我的问题是当我尝试更新已有多个费用行项目的现有费用时.这是我下面的代码,我无法弄清楚问题是什么.该混入(TitleMixin
,CancelSuccessMixin
,SelectedApartment
)是我的,做工精细.
我收到一个错误,我相信,这意味着它正在尝试保存新副本,ExpenseLineItems
但由于那些已经存在而失败.几乎就像我没有提出instance
论点.
我究竟做错了什么?
forms.py
class ExpenseForm(ModelForm):
class Meta:
model = Expense
fields = ['apart', 'inv_num', 'vendor', 'due_date']
ExpenseLineItemFormset = inlineformset_factory(Expense, ExpenseLineItem, fields=('description', 'account', 'amt'), can_delete=False)
Run Code Online (Sandbox Code Playgroud)
这是我的ExpenseUpdate
观点:
class ExpenseUpdate(TitleMixin, CancelSuccessMixin, SelectedApartment, UpdateView):
model = Expense
form_class = ExpenseForm
template_name = 'accounting/expense.html'
def get(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
expense_line_item_form = ExpenseLineItemFormset(instance = self.object)
return self.render_to_response(self.get_context_data(form = form, expense_line_item_form = expense_line_item_form))
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
expense_line_item_form = ExpenseLineItemFormset(self.request.POST, instance=self.object)
if (form.is_valid() and expense_line_item_form.is_valid()):
return self.form_valid(form, expense_line_item_form)
return self.form_invalid(form, expense_line_item_form)
def form_valid(self, form, expense_line_item_form):
self.object = form.save()
expense_line_item_form.instance = self.object
expense_line_item_form.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, expense_line_item_form):
return self.render_to_response(self.get_context_data(form=form, expense_line_item_form=expense_line_item_form))
Run Code Online (Sandbox Code Playgroud)
错误代码我得到:
MultiValueDictKeyError at /stuff/2/accounting/update-expense/25/
"u'expenselineitem_set-0-id'"
Request Method: POST
Request URL: http://localhost:8000/stuff/2/accounting/update-expense/25/
Django Version: 1.8.3
Exception Type: MultiValueDictKeyError
Exception Value:
"u'expenselineitem_set-0-id'"
Exception Location: /usr/local/lib/python2.7/dist-packages/django/utils/datastructures.py in __getitem__, line 322
Run Code Online (Sandbox Code Playgroud)
编辑:我的模板的相关部分:
<form class="form-horizontal" action="" method="post">
{% csrf_token %}
{% load widget_tweaks %}
<div class="row">
<div class="col-md-12">
<table class="table table-tight">
<thead>
<th>Description</th>
<th class="text-right">Account</th>
<th class="text-right">Amount</th>
</thead>
<tbody>
{{ expense_line_item_form.management_form }}
{% for eli in expense_line_item_form %}
<tr>
<td>{{ eli.description|attr:'cols:29' }}</td>
<td class="text-right">{{ eli.account }}</td>
<td class="text-right">{{ eli.amt }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="col-md-12 text-right">
<a href="{{ cancel }}" class="btn btn-default btn-lg">Cancel</a>
<input class="btn btn-success btn-lg" type="submit" value="Post" />
</div>
<br><br>
</form>
Run Code Online (Sandbox Code Playgroud)
编辑 - 工作表单模板我以为我会添加我的模板的工作版本,如果其他人需要它:
<tbody>
{{ expense_line_item_form.management_form }}
{% for eli in expense_line_item_form %}
<tr>
<td>{{ eli.id }} {{ eli.description|attr:'cols:29' }}</td> <!-- <<==== Here's where I simply added {{ eli.id }}. That's all I changed :) -->
<td class="text-right">{{ eli.account }}</td>
<td class="text-right">{{ eli.amt }}</td>
</tr>
{% endfor %}
</tbody>
Run Code Online (Sandbox Code Playgroud)
您需要在formset中包含每个表单的表单ID(它不会显示给用户,因为它将呈现为隐藏输入).如果没有这种形式,POST数据中的值就会丢失,KeyError
您可以看到正确的结果.
注意我们需要如何显式渲染
{{ form.id }}
.这可确保POST案例中的模型formset能够正常工作.(此示例假定名为id的主键.如果您已明确定义了自己的主键,而不是名为id,请确保它已呈现.)
在您的情况下,您循环使用formset {% for eli in expense_line_item_form %}
,因此您需要包含{{ eli.id }}
.
归档时间: |
|
查看次数: |
5391 次 |
最近记录: |