问题描述
我在表单中有一个表格,由表单集生成.
I have a table inside a form, generated by a formset.
在这种情况下,我的问题是在其中一项被修改后保存所有项目,添加一个新的虚拟"列作为其他两项的总和(仅在显示表格时生成,不保存).我尝试了不同的方法,但没有一种方法有效.
In this case, my problem is to save all the items after one of them is modified, adding a new "virtual" column as the sum of other two (that is only generated when displaying the table, not saved). I tried different ways, but no one is working.
问题:
- 这个
save
根本不起作用.它只有一种形式时有效,但不适用于形式集 - 我尝试将
amount
列生成为box_one
和box_two
的Sum
,但没有成功.我也尝试过以这种方式生成表单,但这不起作用:
- This
save
is not working at all. It worked when it was only one form, but not for the formset - I tried to generate the column
amount
as aSum
ofbox_one
andbox_two
without success. I tried generating the form this way too, but this is not working:
这个问题和上一个有关,但是这个新的更简单:使用 Django 从数据库预填充 HTML 表单表
StackOverflow 之前的相关问题已经很老了,对我不起作用.
This issue is related to this previous one, but this new one is simpler: Pre-populate HTML form table from database using Django
我正在使用 Django 2.0.2
Previous related issues at StackOverflow are very old and not working for me.
任何帮助将不胜感激.提前致谢.
I'm using Django 2.0.2
当前代码:
models.py
models.py
views.py
views.py
urls.py
urls.py
item_list.html
item_list.html
...
<div>
<form action="" method="post"></form>
<table>
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<thead>
<tr>
{% if forloop.first %}
<th>{{ form.code.label_tag }} </th>
<th>{{ form.description.label_tag }} </th>
<th> <label>Amount:</label> </th>
<th>{{ form.box_one.label_tag }} </th>
<th>{{ form.box_two.label_tag }} </th>
{% endif %}
</tr>
</thead>
<tbody>
<tr>
<td>{{ form.code }}</td>
<td>{{ form.description }}</td>
<td>{{ form.amount }}</td>
<td>{{ form.box_one }}</td>
<td>{{ form.box_two }}</td>
</tr>
</tbody>
{% endfor %}
<input type="submit" value="Update" />
</table>
</form>
</div>
...
推荐答案
用虚拟列注释查询
Sum
是 聚合表达式 而不是在这种情况下您希望注释此查询的方式.相反,您应该使用 F 表达式 将两个数字字段的值相加
Annotating query with virtual column
Sum
is an aggregate expression and is not how you want to be annotating this query in this case. Instead, you should use an F exrepssion to add the value of two numeric fields
qs.annotate(virtual_col=F('field_one') + F('field_two'))
所以你更正的查询集将是
So your corrected queryset would be
Item.objects.order_by('code__name').annotate(amount=F('box_one') + F('box_two'))
如果打算将该属性仅用于行级"操作,则 cezar 提供的答案非常有用.但是,如果您打算根据amount
进行查询,则需要对查询进行注释.
The answer provided by cezar works great if intend to use the property only for 'row-level' operations. However, if you intend to make a query based on amount
, you need to annotate the query.
您没有在视图类中提供 post
方法.您需要自己提供一个,因为您没有从为您提供一个的通用视图继承.请参阅 使用基于类的视图处理表单.您还应该考虑从处理表单的通用视图继承.例如 ListView
没有实现 post
方法,但 FormView
实现了.
You have not provided a post
method in your view class. You'll need to provide one yourself since you're not inheriting from a generic view that provides one for you. See the docs on Handling forms with class-based views. You should also consider inheriting from a generic view that handles forms. For example ListView
does not implement a post
method, but FormView
does.
请注意,您的模板也不会呈现表单错误.由于您正在手动呈现表单集,因此您应该考虑添加字段错误(例如 {{ form.field.errors}}
),以便在 HTML 中显示验证问题.请参阅关于手动渲染字段的文档.
Note that your template is also not rendering form errors. Since you're rendering the formset manually, you should consider adding the field errors (e.g. {{ form.field.errors}}
) so problems with validation will be presented in the HTML. See the docs on rendering fields manually.
此外,您可以在 post
方法中记录/打印错误.例如:
Additionally, you can log/print the errors in your post
method. For example:
def post(self, request, *args, **kwargs):
formset = MyFormSet(request.POST)
if formset.is_valid():
formset.save()
return SomeResponse
else:
print(formset.errors)
return super().post(request, *args, **kwargs)
如果表单未通过验证,您应该会在控制台/日志中看到错误.
Then if the form does not validate you should see the errors in your console/logs.
这篇关于使用新的“虚拟"保存基于类的视图表单集项目.柱子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!