我尝试创建一个动态表单,使用模型关系生成表单集。
以下是该应用程序的简要概述。我有一个客户表(加入django管理员用户表),产品表,订单表和一些连接表。 customer_product表包含可以编辑的预建订单。我使用一些连接表来创建新的order_instances,可以从历史数据的订单表中引用。
`客户与用户表有一对一的关系
customer table
--------------
id
product table
-------------
id | product_id
`客户拥有并属于许多产品
customer_product (pre-built order templates)
----------------
id | customer_id | product_id
'客户拥有并属于许多产品。客户有很多订单
customer_product_order (customer initiated order)
----------------------
id | customer_id | product_id | order_id | quantity
order (main order table. each record contains meta data for that order)
-------
id | invoice_number | delivery_date
我不知道在这种情况下如何使用formset,这将构建动态表单并保存到customer_product_order表和订单表。目前我有表单输出,但它第二次检查customer_product表,而不是让forms.py oncstruct它。也无法在forms.py页面中构造html数组。
models.py
from django.conf import settings
from django.db import models
from datetime import datetime
import pprint
class Customer(models.Model):
customer = models.ForeignKey(settings.AUTH_USER_MODEL, limit_choices_to={'groups__name': "customers"})
customer_product = models.ManyToManyField('Product', through='CustomerProduct')
company_name = models.CharField(max_length=255)
address1 = models.CharField(max_length=255)
address2 = models.CharField(max_length=255)
city = models.CharField(max_length=255)
state = models.CharField(max_length=255)
zip_code = models.CharField(max_length=255)
created_date = models.DateTimeField('date created')
def __unicode__(self):
return self.company_name
class CustomerProduct(models.Model):
customer = models.ForeignKey('Customer')
product = models.ForeignKey('Product')
def __unicode__(self):
return self.customer.company_name
class Product(models.Model):
item = models.CharField(max_length=255)
description = models.CharField(max_length=255)
def __unicode__(self):
return self.description
class Order(models.Model):
customer_product_order = models.ManyToManyField('CustomerProduct', through='CustomerProductOrder')
purchase_order_number = models.CharField(max_length=10)
person_placing_order = models.CharField(max_length=255)
class CustomerProductOrder(models.Model):
order = models.ForeignKey('Order')
customer_product = models.ForeignKey('CustomerProduct')
quantity = models.IntegerField(default=0)
instructions = models.CharField(max_length=2000)
order_correct = models.BooleanField()
def __unicode__(self):
return self.customer_product.customer.company_name
class Meta:
verbose_name = "Customer Order"
forms.py
from django import forms
from .models import CustomerProduct
class OrderForm(forms.Form):
def __init__(self, *args, **kwargs):
products = CustomerProduct.objects.filter(customer_id=1)
super(OrderForm, self).__init__(*args, **kwargs)
counter = 1
for q in products:
self.fields['product[quantity][' + str(q.id) + ']' + str(counter)] = forms.CharField(required=False)
self.fields['product[item][' + str(q.id) + ']' + str(counter)] = forms.CharField(required=False)
self.fields['product[description][' + str(q.id) + ']' + str(counter)] = forms.CharField(required=False)
counter += 1
purchase_order_number = forms.CharField(required=True)
person_placing_order = forms.CharField(required=True)
delivery_date_request = forms.DateField(required=True,widget=forms.DateInput(attrs={'class':'datepicker'}))
instructions = forms.CharField(required=False,widget=forms.Textarea(attrs={'rows': 5, 'cols': 100, 'class': 'form-control'}))
confirm_order = forms.BooleanField(required=True)
views.py
from django import forms
from .models import CustomerProduct
class OrderForm(forms.Form):
def __init__(self, *args, **kwargs):
products = CustomerProduct.objects.filter(customer_id=1)
super(OrderForm, self).__init__(*args, **kwargs)
counter = 1
for q in products:
self.fields['product[quantity][' + str(q.id) + ']' + str(counter)] = forms.CharField(required=False)
self.fields['product[item][' + str(q.id) + ']' + str(counter)] = forms.CharField(required=False)
self.fields['product[description][' + str(q.id) + ']' + str(counter)] = forms.CharField(required=False)
counter += 1
purchase_order_number = forms.CharField(required=True)
person_placing_order = forms.CharField(required=True)
delivery_date_request = forms.DateField(required=True,widget=forms.DateInput(attrs={'class':'datepicker'}))
instructions = forms.CharField(required=False,widget=forms.Textarea(attrs={'rows': 5, 'cols': 100, 'class': 'form-control'}))
confirm_order = forms.BooleanField(required=True)
模板
{% extends "base.html" %}
{% block orderform %}
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form action="/onlineordering/" method="POST">
<form class="form-inline">
{% csrf_token %}
<div class="row">
<div class="col-md-6">
<div class="form-group">
<div class="row">
<div class="col-md-5"><label for="exampleInputName2">Date</label></div>
<div class="col-md-7">{{ datenow }}</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-5"><label for="exampleInputName2">Customer ID:</label></div>
<div class="col-md-7">{{ username }}</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-5"><label for="exampleInputName2">Address</label></div>
<div class="col-md-7">
1 Main Street<br />
Town<br />
State<br />
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-5"><label for="exampleInputName2">Purchase Order Number</label></div>
<div class="col-md-7">{{ form.purchase_order_number }}</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-5"><label for="exampleInputEmail2">Person Placing Order</label></div>
<div class="col-md-7">{{ form.person_placing_order }}</div>
</div>
</div>
<div class="form-group">
<div class="form-group">
<div class="row">
<div class="col-md-5"><label for="exampleInputEmail2">Requested Delivery Date</label></div>
<div class="col-md-7">{{ form.delivery_date_request }}</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<p class="text-right">
</p>
</div>
</div>
<table class="table table-bordered online-ordering-table">
<tr>
<th width="10%">Quantity</th>
<th width="20%">Item</th>
<th width="70%">Description</th>
</tr>
{% for product in products %}
<tr>
<td><input name="product_quantity" /></td>
<td>{{ product.product.item }}</td>
<td>{{ product.product.description }}</td>
</tr>
{% endfor %}
</table>
<div class="form-group">
<label for="exampleInputEmail2">Special Instructions / Comments</label>
{{ form.instructions }}
</div>
<div class="form-group">
<div class="checkbox">
<label>
{{ form.confirm_order }} I concede the order above is correct and authorize Company to fulfill this order
</label>
</div>
</div>
<input class="btn" type="submit" value="Submit">
</form>
</form>
{% endblock %}
更新
关于模特的评论。我尽可能地详细说明了上面的关系。该应用程序的设计和要求如下。每个客户都有用户。客户订单表由管理员预先构建并存储在customer_product表中。客户 hasandomanstomany 产品和客户 hasmanyorders 。当客户下订单时,会添加新的订单记录,并填充customer_products_order连接表以及每个产品的数量。
customer_product表由管理员预先填充。 customer_product_order(加入)和订单表由客户填充。
我使用以下联接从订单模型中获取客户信息。我找不到任何其他方式来递归加入订单模型中的客户表。我可能错了。即使这超出了这个问题,我也非常感谢对我的代码提出任何意见!
models.ManyToManyField('CustomerProduct', through='CustomerProductOrder')
答案 0 :(得分:2)
从我们在评论和您更新的答案中开始的讨论中,我不确定您customer_product
表的目的是什么?如果我最终得到它,我会更新我的答案。
(在我看来,customer_id
模型中的customer_product
字段与customer_id
中的customer_product_order
字段是多余的,使得表格customer_product
成为可能实际上并没有用。)
要为产品订购系统建模,您可以在customer_id
级别移动order
(根据我对您的要求的理解,Customer
有许多订单,但是订单有一个单个客户,当前设计无法实现),为您提供:
product_order
----------------------
id | product_id(ForeignKey) | order_id(ForeignKey) | quantity
order
-------
id | customer_id(ForeignKey) | invoice_number | delivery_date
如果这种模式可以满足您的需求,您能否澄清一下您面临的问题是什么?
编辑:我认为数据建模略有偏差,并且没有传达关于您要实现的目标的正确信息(使其变得复杂起来;)。特别是:
客户拥有和属于您的产品
似乎这可能是一种误解:为什么客户属于某种产品?
Customer
与Order
个实例之间存在多与一个 关系似乎更为自然。 Order
与Products
之间存在多对多一个 关系,可能通过包含quantity
的外部表加入字段(即您的CustomerProductOrder
表)。
这会给你这个更新和简化的模型:
customer table
--------------
id | ...
product table
-------------
id | description | ...
order
-------
id | customer_id(ForeignKey) | person_placing_order | invoice_number | delivery_date
order_content (~= customer_product_order)
----------------------
id | order_id(ForeignKey) | customer_id | product_id(ForeignKey) | product_quantity
请您解释为什么这个更琐碎的设计不适合您的目的? (希望它能让我们更好地了解您的要求)