Abe*_*Paz 10 python django save formset
我在表单中有一个表格,由formset生成.
在这种情况下,我的问题是在修改其中一个项目之后保存所有项目,添加一个新的"虚拟"列作为其他两个的总和(仅在显示表时生成,未保存).我尝试了不同的方法,但没有人工作.
问题:
save根本不起作用.当它只是一种形式时它起作用,但不适用于形式amount作为Sum的box_one并box_two没有成功.我也试过这种方式生成表单,但这不起作用:Run Code Online (Sandbox Code Playgroud)formset = modelformset_factory( Item, form=ItemForm)(queryset=Item.objects.order_by( 'code__name').annotate(amount=Sum('box_one') + Sum('box_two')))
此问题与前一个问题有关,但这个新问题更简单: 使用Django从数据库预填充HTML表单表
StackOverflow以前的相关问题很老,对我不起作用.
我正在使用Django 2.0.2
任何帮助,将不胜感激.提前致谢.
当前代码:
models.py
class Code(models.Model):
name = models.CharField(max_length=6)
description = models.CharField(max_length=100)
def __str__(self):
return self.name
class Item(models.Model):
code = models.ForeignKey(Code, on_delete=models.DO_NOTHING)
box_one = models.IntegerField(default=0)
box_two = models.IntegerField(default=0)
class Meta:
ordering = ["code"]
Run Code Online (Sandbox Code Playgroud)
views.py
class ItemForm(ModelForm):
description = CharField()
class Meta:
model = Item
fields = ['code', 'box_one', 'box_two']
def save(self, commit=True):
item = super(ItemForm, self).save(commit=commit)
item.box_one = self.cleaned_data['box_one']
item.box_two = self.cleaned_data['box_two']
item.code.save()
def get_initial_for_field(self, field, field_name):
if field_name == 'description' and hasattr(self.instance, 'code'):
return self.instance.code.description
else:
return super(ItemForm, self).get_initial_for_field(
field, field_name)
class ItemListView(ListView):
model = Item
def get_context_data(self, **kwargs):
data = super(ItemListView, self).get_context_data()
formset = modelformset_factory(Item, form=ItemForm)()
data['formset'] = formset
return data
Run Code Online (Sandbox Code Playgroud)
urls.py
app_name = 'inventory'
urlpatterns = [
path('', views.ItemListView.as_view(), name='index'),
Run Code Online (Sandbox Code Playgroud)
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>
...
Run Code Online (Sandbox Code Playgroud)
你已经走在正确的道路上了。所以你说你需要一个虚拟专栏。您可以在模型类中定义虚拟属性,该属性不会存储在数据库表中,但可以像模型类的任何其他属性一样访问它。
这是您应该添加到模型类中的代码Item:
class Item(models.Model):
# existing code
@property
def amount(self):
return self.box_one + self.box_one
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
item = Item.objects.get(pk=1)
print(item.box_one) # return for example 1
print(item.box_two) # return for example 2
print(item.amount) # it will return 3 (1 + 2 = 3)
Run Code Online (Sandbox Code Playgroud)
编辑:
通过ModelForm我们可以访问模型实例,从而访问它的所有属性。在模板中渲染模型表单时,我们可以访问如下属性:
{{ form.instance.amount }}
Run Code Online (Sandbox Code Playgroud)
虚拟财产背后的想法amount是将业务逻辑放置在模型中,并遵循胖模型-瘦控制器的方法。因此, and的as amountsum可以在不同的地方重用,而无需重复代码。box_onebox_two
| 归档时间: |
|
| 查看次数: |
240 次 |
| 最近记录: |