Django的形式与来自数据库填充输入
我有产品和订单的简单的Django模型结构中,通过确定一个给定的顺序中的每个产品的数量的中间表链接:Django的形式与来自数据库填充输入
models.py:
class Product(models.Model):
name = models.CharField()
class Order(models.Model):
id = models.IntegerField()
products = models.ManyToManyField(Product, through='OrderProduct')
class OrderProduct(models.Model):
order=models.ForeignKey(Order, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveSmallIntegerField()
我想在我的forms.py文件中设计一个表单,该表单1)拉取数据库中每个产品的列表; 2)为用户提供了调整每个订购产品数量的选项(例如,在CharField输入中),以及3)创建新的Order和OrderProduct对象,存储用户订购的每个产品的数量记录。
但是,我找不到一个好方法来创建一个表单,它将自动从数据库中提取所有产品,并添加字段来表示给定产品的订购数量。理想情况下,结果会是这个样子,但自动编码:
forms.py:
class OrderForm(forms.Form):
product_1_quantity = forms.IntegerField()
product_2_quantity = forms.IntegerField()
product_3_quantity = forms.IntegerField()
....等,每个产品。什么是最好的方法来做到这一点?它是否涉及为数据库中的每个产品创建新字段的for循环?
我认为Django Formsets可能对您有用。根据您决定的数量,您可以反复创建相同表单的集合,因此您的产品。检查出来here。你可以做下面的例子。
class ArticleForm(forms.Form):
title = forms.CharField()
from django.forms import formset_factory
ArticleFormSet = formset_factory(ArticleForm, extra=2)
的数据如您还可以预填充它,
formset = ArticleFormSet(initial=[
{'title': 'Django is now open source'}
])
希望这有助于!
您可以使用ModelChoiceField
显示所有产品无for循环做:
class OrderForm(forms.Form):
product = forms.ModelChoiceField(queryset=Product.objects.all()) # with queryset you can show a checkbox with the query
quantify = forms.IntegerField()
现在你的观点要小心保存您的数据。例如,如果你需要一个按钮“添加新的”,你可以使用ajax,否则you can use formset
感谢您的回应!我试过这个,但是这会产生一个'select'下拉列表,而我想为我的数据库中的每个产品单独一行,旁边有一个数量字段。 Formset在这里完成了目标 - 请参阅上面的答案! – Sam
详细说明从user3140312下面的答案 - Django的formsets提供了解决方案!
models.py:
class Product(models.Model):
name = models.CharField()
class Order(models.Model):
id = models.IntegerField()
products = models.ManyToManyField(Product, through='OrderProduct')
class OrderProduct(models.Model):
order=models.ForeignKey(Order, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveSmallIntegerField()
forms.py:
class ProductForm(forms.Form):
product_id = forms.IntegerField(widget=forms.HiddenInput)
quantity = forms.IntegerField()
views.py:
from .forms import ProductForm
from django.forms import formset_factory
from .models import Product
# Show a form asking for the user's product quantities
def product_form(request):
# If this form is being processed...
if request.method == 'POST':
ProductFormSet = formset_factory(ProductForm)
# Grab the form from the POST variable
formset = ProductFormSet(request.POST)
# If the form is valid...
if formset.is_valid():
# Do whatever you want with the results
# If the form is not being processed, create a new ProductFormSet and render it
else:
product_list = []
for product in Product.objects.all():
product_list.append({'product_id': product.id, 'quantity': 0})
ProductFormSet = formset_factory(ProductForm, extra=0)
formset = ProductFormSet(initial=product_list)
return render(request, 'template.html', {'formset': formset})
template.html:
<form action="{% url '' %}" method="post">
{% csrf_token %}
{{ formset.as_table }}
{{ formset.management_form }}
<input type="submit" value="Submit" />
</form>
不要忘记接受来自@ user3140312 –
完成的答案。谢谢! – Sam
这很好用 - 非常感谢您的帮助!我将在另一篇文章中更详细地回答这个问题,以便人们可以看到整个代码。 – Sam
很高兴我可以帮助:) – devdob