Saving class-based view formset items with a new quot;virtualquot; column(使用新的“虚拟保存基于类的视图表单集项目.柱子)

本文介绍了使用新的“虚拟"保存基于类的视图表单集项目.柱子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在表单中有一个表格,由表单集生成.

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_onebox_twoSum ,但没有成功.我也尝试过以这种方式生成表单,但这不起作用:
  • 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 a Sum of box_one and box_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
<form action="" method="post"></form><桌子>{% csrf_token %}{{ formset.management_form }}{% for formset %}<头><tr>{% if forloop.first %}<th>{{ form.code.label_tag }} </th><th>{{ form.description.label_tag }} </th><th><label>金额:</label></th><th>{{ form.box_one.label_tag }} </th><th>{{ form.box_two.label_tag }} </th>{% 万一 %}</tr></头><身体><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 %}<输入类型=提交"值=更新"/></表></表格></div>...

... <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 表达式 将两个数字字段的值相加

Annotatingquerywithvirtualcolumn

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.

这篇关于使用新的“虚拟"保存基于类的视图表单集项目.柱子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!