在中间模型中保存ManyToMany字段数据时出现问题
首先,对不起我的英语。
我有这样的结构,想法是: 产品可以有很多供应商,供应商自己也有产品
class Supplier(Model):
title = CharField()
def add_product(self, **kwargs):
s2p = Stock(supplier=self, **kwargs)
s2p.save()
class Product(Model):
title = CharField()
stock = ManyToManyField(Supplier, through="Stock")
class Stock(Model):
in_stock = BooleanField()
product = ForeignKey(Product, related_name="product_stock")
supplier = ForeignKey(Supplier, related_name="supplier_stock")
# forms.py
class ProductForm(ModelForm):
class Meta:
model = Product
stock = ModelChoiceField(queryset=Supplier.objects.all(), widget=CheckboxSelectMultiple)
# views.py
def product_edit(request, product_id, template):
if product_id:
product = get_object_or_404(Product, pk=product_id)
else:
product = Product()
if request.method == "POST":
data = request.POST.copy()
form = ProductForm(data, request.FILES, instance=product)
if form.is_valid():
prod = form.save(commit=False)
if product.id:
prod.editedby = product.editedby
else:
prod.createdby = request.user
prod.editedby = request.user
prod.save()
if "stock" in request.POST:
actions.clear_stock()
suppliers = data.get('stock','')
for supplier in suppliers:
supp = Supplier.objects.get(pk=supplier)
supp.add_product(product=prod)
else:
form = ProductForm(instance=product)
dict = {
'form': form,
}
return render_to_response(template, dict, context_instance=RequestContext(request))
# actions.py
def clear_stock():
s2ps = Stock.objects.all()
for s2p in s2ps:
s2p.delete()
当我添加产品时,它必须与供应商相关,我使用这种类型的逻辑:
- 解析POST数据字段“stock”,其中存储供应商的ID
- 然后在for中循环我通过ID获取供应商的实例,该实例之前从POST获取,并存储在“供应商”中
- 对于每个“供应商”,我通过ID获取实例
- 然后使用Supplier.add_product模型函数将它们添加到数据库中
问题是,只有列表中的最后一个供应商已添加到数据库
希望我解释了这个问题。
First of all, sorry for my English.
I have this structure, idea is:
Product can have many suppliers, and supplier himself have products
class Supplier(Model):
title = CharField()
def add_product(self, **kwargs):
s2p = Stock(supplier=self, **kwargs)
s2p.save()
class Product(Model):
title = CharField()
stock = ManyToManyField(Supplier, through="Stock")
class Stock(Model):
in_stock = BooleanField()
product = ForeignKey(Product, related_name="product_stock")
supplier = ForeignKey(Supplier, related_name="supplier_stock")
# forms.py
class ProductForm(ModelForm):
class Meta:
model = Product
stock = ModelChoiceField(queryset=Supplier.objects.all(), widget=CheckboxSelectMultiple)
# views.py
def product_edit(request, product_id, template):
if product_id:
product = get_object_or_404(Product, pk=product_id)
else:
product = Product()
if request.method == "POST":
data = request.POST.copy()
form = ProductForm(data, request.FILES, instance=product)
if form.is_valid():
prod = form.save(commit=False)
if product.id:
prod.editedby = product.editedby
else:
prod.createdby = request.user
prod.editedby = request.user
prod.save()
if "stock" in request.POST:
actions.clear_stock()
suppliers = data.get('stock','')
for supplier in suppliers:
supp = Supplier.objects.get(pk=supplier)
supp.add_product(product=prod)
else:
form = ProductForm(instance=product)
dict = {
'form': form,
}
return render_to_response(template, dict, context_instance=RequestContext(request))
# actions.py
def clear_stock():
s2ps = Stock.objects.all()
for s2p in s2ps:
s2p.delete()
When i add product, it must be related to supplier(s), i use this type of logic:
- Parsing POST data field "stock", where IDs of supplier is stored
- Then in for loop i get instance for supplier by ID, which was previously get from POST, and stored in "suppliers"
- For each of "Supplier" i get instance by ID
- Then add them to database with Supplier.add_product model function
The problem is, that only last supplier from the list is added to database
Hope I explained the problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
另一个解决方案是将表单字段更改为 ModelMultipleChoiceField。然后您将能够迭代 form.cleaned_data['stock'] ,这将为您提供所选供应商的实际实例。这避免了直接处理 POST QueryDict,也消除了“手动”执行供应商查询的需要。
Another solution is to change your form field to a ModelMultipleChoiceField. Then you would be able to iterate form.cleaned_data['stock'] which would give you the actual instances of Supplier which were selected. This avoids dealing with the POST QueryDict directly and also removes the need to do the Supplier queries "manually".
您想将其更改
为:
QueryDict.get('foo')
仅返回foo
的一个值,即使foo< 有多个值/代码>。请参阅 QueryDict.getlist 的文档()
。You want to change this:
to this:
QueryDict.get('foo')
only returns one value forfoo
, even if there are multiple values forfoo
. See the documentation forQueryDict.getlist()
.