2017-11-11 108 views
0

我有产品和订单的简单的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循环?

回答

1

我认为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'} 
    ]) 

希望这有助于!

+0

这很好用 - 非常感谢您的帮助!我将在另一篇文章中更详细地回答这个问题,以便人们可以看到整个代码。 – Sam

+0

很高兴我可以帮助:) – devdob

0

您可以使用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

+0

感谢您的回应!我试过这个,但是这会产生一个'select'下拉列表,而我想为我的数据库中的每个产品单独一行,旁边有一个数量字段。 Formset在这里完成了目标 - 请参阅上面的答案! – Sam

0

详细说明从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> 
+0

不要忘记接受来自@ user3140312 –

+0

完成的答案。谢谢! – Sam