python - 基于 Django 类的表单仅更新最终的帖子值
问题描述
正如标题所述,我有一个我正在尝试更新的表,它只更新帖子中的最终值,据我所知,如果我想更新多条记录,我必须遍历我的请求对象并更新表单实例我的数据库中指定的 ID。
在提交之前,所有记录的 aprice_checked
为 0。
然后之后 - 您可以从发布请求中看到最终值更新了所有记录!
postgres table
有问题的代码更新了我的模型表单实例。
def post(self,request):
if request.method=='POST':
for key in request.POST.getlist('product_id'):
product_update = ProductTable.objects.get(id=key)
form = ProductUpdateForm(request.POST,instance=product_update)
print(form)
if form.is_valid():
form.save()
messages.success(request,message='price checked...')
return redirect('product')
有人可以帮忙吗?我已经在这一点上超过 2 周了。
模型/表格/视图供参考。
models.py
from django.db import models
class ProductTable(models.Model):
id = models.AutoField(
primary_key=True,
editable=False
)
product_name = models.TextField(max_length=255,null=False)
price = models.DecimalField(max_digits=6,decimal_places=2,null=False)
from_date = models.DateTimeField()
to_date = models.DateTimeField(null=True)
price_checked = models.IntegerField(default=0,null=False)
def __str__(self : str) -> str:
return f"{self.product_name} - {self.id} with a price check of {self.price_checked}"
forms.py
from django.forms import ModelForm
from .models import ProductTable
class ProductUpdateForm(ModelForm):
class Meta:
model = ProductTable
fields = ('price_checked',)
views.py
from typing import Any, Dict
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import redirect
from django.views.generic import ListView
from django.db import transaction
from .forms import ProductUpdateForm
from .models import ProductTable
class TableDataView(LoginRequiredMixin,ListView):
model = ProductTable
context_object_name = 'product'
template_name = 'tables/product.html'
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
context = super().get_context_data(**kwargs)
context['product'] = ProductTable.objects.filter(pk__in= [4607,4642, 4645])
return context
def post(self,request):
if request.method=='POST':
for key in request.POST.getlist('product_id'):
product_update = ProductTable.objects.get(id=key)
form = ProductUpdateForm(request.POST,instance=product_update)
print(form)
if form.is_valid():
form.save()
messages.success(request,message='price checked...')
return redirect('product')
product.html
{% extends '_base.html' %} {% block content %} {% load crispy_forms_tags %}
<form method="POST" action="">
{% csrf_token %}
{{ form|crispy }}
<div class="container mx-flex pt-5 mb-5">
<table class="table" id="table">
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Date</th>
<th>Input</th>
</tr>
</thead>
<tbody>
{% for data in product %}
<tr>
<th>{{ data.product_name }}</th>
<th>{{ data.price }}</th>
<th>{{ data.from_date }}</th>
<th>
<input type="hidden" name="product_id" value="{{data.id}}" />
<input class="form" name="price_checked" id="priced_checked" type="number" placeholder="{{ data.price_checked }}"/>
<input type="submit" value="OK">
</th>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</form>
{% endblock content %}
request.POST
<QueryDict: {'csrfmiddlewaretoken': ['p0j3e0UbrY1VuFEAnJWopaCICCxOPj8v2OkLRZZiGlUa4YtxGwduD2bAIrm91VKe'], 'product_id': ['4607', '4642', '4645'], 'price_checked': ['1', '2', '3']}>
解决方案
阅读表单集文档后,我认为它应该是这样的。
视图python将一个表单集返回给模板,并在post
函数中创建表单集request.POST
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
context = super().get_context_data(**kwargs)
ProductFormSet = modelformset_factory(ProductTable)
context['product_formset'] = ProductFormSet(queryset=ProductTable.objects.filter(pk__in= [4607,4642, 4645]))
return context
def post(self,request):
if request.method=='POST':
ProductFormSet = modelformset_factory(ProductTable)
formset = ProductFormSet(request.POST)
if formset.is_valid():
formset.save()
messages.success(request,message='price checked...')
return redirect('product')
在模板中我已经标记了更改,重要的是{{ product_formset.management_form }}
在开始表单{{ form.id }}
中。每个循环,每个单元格数据应该是{{ form.product_name.value() }}
或{{ form.product_name.data }}
,你可以试试
{% extends '_base.html' %} {% block content %} {% load crispy_forms_tags %}
<form method="POST" action="">
{% csrf_token %}
{{ form|crispy }}
<!-- changed -->
{{ product_formset.management_form }}
<div class="container mx-flex pt-5 mb-5">
<table class="table" id="table">
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Date</th>
<th>Input</th>
</tr>
</thead>
<tbody>
<!-- changed -->
{% for form in product_formset %}
{{ form.id }}
<tr>
<td>{{ form.product_name.value() }}</td>
<td>{{ form.price.value() }}</td>
<td>{{ form.from_date.value() }}</td>
<td>
{{ form.price_checked }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<input type="submit" value="submit">
</form>
{% endblock content %}
也许这对你没有帮助,因为我从来没有使用过 django 形式的东西。
我猜你是一个想要遵循每个 django 原则的精确人。
但据我所知,传统形式有很多限制,一些 ajax 或 reactjs 更灵活。
推荐阅读
- arrays - 在 Kotlin 中调用类的数组时,如何在函数中指定元素?
- go - 这种类型断言的目的是什么
- javascript - 不可能用点自定义 react-bootstrap 轮播
- excel - 隐藏表格 vba
- vue.js - 如何在 Vuejs 中使用离子电话号码插件?
- android - 颤振:引发了另一个异常:NoSuchMethodError:在 null 上调用了 getter '_duration'
- python-3.x - 有没有办法遍历随包安装的模块?
- c# - 是否可以在运行时覆盖 Environment.GetCommandLineArgs()?
- php - 遍历从php中的api获取的数组值
- javascript - 通过 JS 添加类或不通过 PHP 在某些用户 IP 上输出 html