在中间模型中保存多对多字段数据的问题

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'],但我也没有返回列表。

以上是关于在中间模型中保存多对多字段数据的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 中为多对多关系(和中间表)做一个选择字段?

如何使用 django rest 框架保存多对多字段对象

当我使用中间模型时,如何建立强制唯一性的多对多关系?

与 Shopware 6 中的其他字段的多对多关联

与对象的多对多关系,其中存在中间字段?

复制多对多值