在中间模型中保存多对多字段数据的问题
Posted
技术标签:
【中文标题】在中间模型中保存多对多字段数据的问题【英文标题】:Problem with saving ManyToMany field data in intermediary models 【发布时间】:2011-08-03 01:14:03 【问题描述】:首先,对不起我的英语。
我有这个结构,想法是: 产品可以有很多供应商,而供应商自己也有产品
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()
当我添加产品时,它必须与供应商相关,我使用这种逻辑:
-
解析存储供应商 ID 的 POST 数据字段“stock”
然后在 for 循环中,我通过 ID 获取供应商的实例,该 ID 之前从 POST 获取,并存储在“供应商”中
对于每个“供应商”,我通过 ID 获取实例
然后使用 Supplier.add_product 模型函数将它们添加到数据库中
问题是,只有列表中的最后一个供应商被添加到数据库中
希望我能解释问题。
【问题讨论】:
【参考方案1】:另一种解决方案是将表单字段更改为 ModelMultipleChoiceField。然后,您将能够迭代 form.cleaned_data['stock'] 这将为您提供已选择的供应商的实际实例。这避免了直接处理 POST QueryDict 并且还消除了“手动”执行供应商查询的需要。
【讨论】:
【参考方案2】:你想改变这个:
data.get('stock','')
到这里:
data.getlist('stock')
QueryDict.get('foo')
只为foo
返回一个值,即使foo
有多个值。请参阅documentation for QueryDict.getlist()
。
【讨论】:
天啊!它有效,无法想象它会这么容易!谢谢:)顺便说一句,我尝试使用 data['stock'],但我也没有返回列表。以上是关于在中间模型中保存多对多字段数据的问题的主要内容,如果未能解决你的问题,请参考以下文章